Compare commits
10 Commits
a49d3f31e6
...
6231bc2a3b
Author | SHA1 | Date | |
---|---|---|---|
6231bc2a3b | |||
![]() |
b3345f64fe | ||
![]() |
80c8527ce3 | ||
![]() |
7df593f721 | ||
![]() |
65d62e131a | ||
![]() |
016b5a591a | ||
![]() |
cbb3f34dfb | ||
![]() |
90122ec55d | ||
![]() |
f099ac6a85 | ||
521ffd29c9 |
11
README.md
11
README.md
@ -8,9 +8,20 @@ This project contains my dotfiles and scripts for daily usage. In addition to th
|
||||
- alacritty
|
||||
- xmobar
|
||||
- dunst
|
||||
- nnn
|
||||
- bash
|
||||
- dircolours
|
||||
- dmenu
|
||||
- border patch
|
||||
- center patch
|
||||
- lineheight patch
|
||||
- zenburn colour sheme
|
||||
- mapped j-k to down-up and h-l to prior-next
|
||||
- slock
|
||||
- neovim
|
||||
- git
|
||||
- git delta
|
||||
- lazygit
|
||||
- scripts
|
||||
- `compiledoc` - compile a markdown or latex file into pdf using pandoc and tectonic
|
||||
- `open_editor_in_new_shell` - used by nnn to open a file in `$EDITOR` in a new `$TERMINAL`
|
||||
|
1040
ansible.cfg
Normal file
1040
ansible.cfg
Normal file
File diff suppressed because it is too large
Load Diff
24
justfile
24
justfile
@ -3,15 +3,23 @@ allTags := "nvim,xmonad,git,scripts"
|
||||
default:
|
||||
just --list
|
||||
|
||||
sync-qwerty tags=allTags:
|
||||
ANSIBLE_LOCALHOST_WARNING=false ansible-playbook site.yml -K -t "pc,qwerty,{{tags}}"
|
||||
setup-qwerty tags=allTags:
|
||||
ansible-playbook site.yml -K -t "pc,qwerty,{{tags}}"
|
||||
|
||||
sync-x220 tags=allTags:
|
||||
ANSIBLE_LOCALHOST_WARNING=false ansible-playbook site.yml -K -t "pc,x220,{{tags}}"
|
||||
config-qwerty tags=allTags:
|
||||
ansible-playbook site.yml -t "pc,qwerty,{{tags}}" --skip-tags "setup"
|
||||
|
||||
sync-t460p tags=allTags:
|
||||
ANSIBLE_LOCALHOST_WARNING=false ansible-playbook site.yml -K -t "pc,t460p,{{tags}}"
|
||||
setup-x220 tags=allTags:
|
||||
ansible-playbook site.yml -K -t "pc,x220,{{tags}}"
|
||||
|
||||
config-x220 tags=allTags:
|
||||
ansible-playbook site.yml -t "pc,x220,{{tags}}" --skip-tags "setup"
|
||||
|
||||
setup-t460p tags=allTags:
|
||||
ansible-playbook site.yml -K -t "pc,t460p,{{tags}}"
|
||||
|
||||
config-t460p tags=allTags:
|
||||
ansible-playbook site.yml -t "pc,t460p,{{tags}}" --skip-tags "setup"
|
||||
|
||||
sync-server tags=allTags:
|
||||
ANSIBLE_LOCALHOST_WARNING=false ansible-playbook site.yml -K -t "server,{{tags}}"
|
||||
|
||||
ansible-playbook site.yml -K -t "server,{{tags}}"
|
||||
|
@ -167,7 +167,7 @@ for _, server in ipairs(servers) do
|
||||
}
|
||||
end
|
||||
|
||||
lsp.sumneko_lua.setup {
|
||||
lsp.lua_ls.setup {
|
||||
on_attach = on_attach,
|
||||
capabilities = capabilities,
|
||||
settings = {
|
||||
|
@ -7,14 +7,14 @@
|
||||
- git
|
||||
- xclip
|
||||
state: present
|
||||
tags: always
|
||||
tags: [always, setup]
|
||||
|
||||
- name: Create a config directory if it doesn't exist
|
||||
ansible.builtin.file:
|
||||
path: ~/.config/nvim
|
||||
state: directory
|
||||
mode: '0755'
|
||||
tags: always
|
||||
tags: [always, setup]
|
||||
|
||||
- name: Server specific nvim tasks
|
||||
tags: server
|
||||
@ -41,6 +41,7 @@
|
||||
mode: '0755'
|
||||
|
||||
- name: Install language servers
|
||||
tags: setup
|
||||
become: true
|
||||
ansible.builtin.package:
|
||||
name:
|
||||
|
@ -29,6 +29,8 @@ case "$ext" in
|
||||
-V geometry:margin=2cm \
|
||||
-V mainfont="Liberation Sans" \
|
||||
-V monofont="Liberation Mono" \
|
||||
--highlight-style tango \
|
||||
--include-in-header ~/.local/bin/inline_code.tex \
|
||||
-o "$base".pdf "$file" ;;
|
||||
tex) compile_tex ;;
|
||||
esac
|
||||
|
14
roles/scripts/files/dmenu_screenshot
Normal file
14
roles/scripts/files/dmenu_screenshot
Normal file
@ -0,0 +1,14 @@
|
||||
#! /usr/bin/env sh
|
||||
# Changed a bit from Luke Smith https://github.com/LukeSmithxyz/voidrice/blob/master/.local/bin/maimpick
|
||||
# A dmenu for selecting a screenshot option as listed below. Requires maim, xdotool and dmenu.
|
||||
|
||||
DEST="/home/max/bilder/screenshots/screenshot_$(date +%Y-%m-%d_%T).png"
|
||||
|
||||
case "$(printf "a selected area\\ncurrent window\\nfull screen\\na selected area (to clipboard)\\ncurrent window (to clipboard)\\nfull screen (to clipboard)" | dmenu -i -p "Screenshot which area?")" in
|
||||
"a selected area") maim -u -s $DEST ;;
|
||||
"current window") maim -u -i "$(xdotool getactivewindow)" $DEST ;;
|
||||
"full screen") maim -u -B -d '0.8' --quiet $DEST ;;
|
||||
"a selected area (to clipboard)") maim -s -u | xclip -selection clipboard -t image/png ;;
|
||||
"current window (to clipboard)") maim -u -i "$(xdotool getactivewindow)" | xclip -selection clipboard -t image/png ;;
|
||||
"full screen (to clipboard)") maim | xclip -selection clipboard -t image/png ;;
|
||||
esac
|
8
roles/scripts/files/inline_code.tex
Normal file
8
roles/scripts/files/inline_code.tex
Normal file
@ -0,0 +1,8 @@
|
||||
\usepackage{fancyvrb,newverbs,xcolor}
|
||||
|
||||
\definecolor{Light}{HTML}{F8F8F8}
|
||||
|
||||
\let\oldtexttt\texttt
|
||||
\renewcommand{\texttt}[1]{
|
||||
\colorbox{Light}{\oldtexttt{#1}}
|
||||
}
|
3
roles/scripts/files/open_editor_in_new_shell
Normal file
3
roles/scripts/files/open_editor_in_new_shell
Normal file
@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
$TERMINAL -e $EDITOR $1 &
|
@ -5,6 +5,8 @@
|
||||
- tectonic
|
||||
- pandoc
|
||||
- ttf-liberation
|
||||
- maim
|
||||
- xdotool
|
||||
state: present
|
||||
become: true
|
||||
tags: pc
|
||||
@ -23,4 +25,7 @@
|
||||
mode: '0755'
|
||||
with_items:
|
||||
- { src: compiledoc, dest: ~/.local/bin/compiledoc }
|
||||
- { src: inline_code.tex, dest: ~/.local/bin/inline_code.tex }
|
||||
- { src: open_editor_in_new_shell, dest: ~/.local/bin/open_editor_in_new_shell }
|
||||
- { src: dmenu_screenshot, dest: ~/.local/bin/dmenu_screenshot }
|
||||
tags: pc
|
||||
|
78
roles/xmonad/files/bashrc_t460p
Normal file
78
roles/xmonad/files/bashrc_t460p
Normal file
@ -0,0 +1,78 @@
|
||||
# ~/.bashrc
|
||||
|
||||
# colouring terminal
|
||||
export PS1='\[\033[38;5;174m\]\u\[\033[38;5;187m\]@\h\[\033[00m\]:\[\033[38;5;174m\] \w \[\033[00m\]\$ '
|
||||
|
||||
# colouring ls
|
||||
eval $(dircolors -b $HOME/.config/dircolours)
|
||||
|
||||
# set vi mode for bash
|
||||
set -o vi
|
||||
|
||||
# aliases
|
||||
alias ls='ls --color'
|
||||
alias la='ls -lah'
|
||||
|
||||
alias gf='git fetch'
|
||||
alias gd='git diff'
|
||||
alias gl='git log'
|
||||
alias gpl='git pull'
|
||||
alias gps='git push'
|
||||
alias ga='git add'
|
||||
alias gst='git status'
|
||||
alias gck='git checkout'
|
||||
alias gcm='git commit'
|
||||
alias gcl='git clone'
|
||||
alias gb='git branch'
|
||||
alias gr='git reset'
|
||||
alias grm='git rm'
|
||||
|
||||
# starting ssh-agent
|
||||
if [ -z "$SSH_AUTH_SOCK" ] ; then
|
||||
eval `ssh-agent -s` 2>&1 >/dev/null
|
||||
fi
|
||||
|
||||
# nnn config
|
||||
export NNN_OPTS="eE"
|
||||
export NNN_COLORS='#a744b322'
|
||||
export NNN_FCOLORS='dfdfdf6c0000df42bbbaba5f'
|
||||
export NNN_TRASH=1
|
||||
export NNN_ARCHIVE="\\.(7z|a|ace|alz|arc|arj|bz|bz2|cab|cpio|deb|gz|jar|lha|lz|lzh|lzma|lzo|rar|rpm|rz|t7z|tar|tbz|tbz2|tgz|tlz|txz|tZ|tzo|war|xpi|xz|Z|zip)$"
|
||||
export NNN_BMS='b:~/bilder;d:~/downloads;D:~/dokumente;v:~/videos;m:~/music;c:~/.config'
|
||||
export NNN_PLUG='m:nmount'
|
||||
|
||||
# nnn cd on quit
|
||||
n ()
|
||||
{
|
||||
# Block nesting of nnn in subshells
|
||||
if [ -n $NNNLVL ] && [ "${NNNLVL:-0}" -ge 1 ]; then
|
||||
echo "nnn is already running"
|
||||
return
|
||||
fi
|
||||
|
||||
NNN_TMPFILE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.lastd"
|
||||
|
||||
nnn "$@"
|
||||
|
||||
if [ -f "$NNN_TMPFILE" ]; then
|
||||
. "$NNN_TMPFILE"
|
||||
rm -f "$NNN_TMPFILE" > /dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
# vimwiki
|
||||
vw () {
|
||||
if [[ $# == 0 ]]
|
||||
then
|
||||
git -C ~/.local/share/vimwiki pull
|
||||
nvim ~/.local/share/vimwiki/index.md
|
||||
git -C ~/.local/share/vimwiki add ~/.local/share/vimwiki/*
|
||||
git -C ~/.local/share/vimwiki commit -m "autosync-$(date +%FT%T)"
|
||||
git -C ~/.local/share/vimwiki push
|
||||
elif [[ $1 == 'g' ]]
|
||||
then
|
||||
git -C ~/.local/share/vimwiki ${@:2}
|
||||
else
|
||||
echo 'Usage: vw [g] [args ...]'
|
||||
fi
|
||||
}
|
268
roles/xmonad/files/dircolours
Normal file
268
roles/xmonad/files/dircolours
Normal file
@ -0,0 +1,268 @@
|
||||
# Zenburn color theme for the color GNU ls utility.
|
||||
# Ivaylo Kuzev <ivkuzev@gmail.com>, 2014 - 2015
|
||||
|
||||
# Term Section
|
||||
TERM Eterm
|
||||
TERM ansi
|
||||
TERM color-xterm
|
||||
TERM con132x25
|
||||
TERM con132x30
|
||||
TERM con132x43
|
||||
TERM con132x60
|
||||
TERM con80x25
|
||||
TERM con80x28
|
||||
TERM con80x30
|
||||
TERM con80x43
|
||||
TERM con80x50
|
||||
TERM con80x60
|
||||
TERM cons25
|
||||
TERM console
|
||||
TERM cygwin
|
||||
TERM dtterm
|
||||
TERM eterm-color
|
||||
TERM gnome
|
||||
TERM gnome-256color
|
||||
TERM jfbterm
|
||||
TERM konsole
|
||||
TERM kterm
|
||||
TERM linux
|
||||
TERM linux-c
|
||||
TERM mach-color
|
||||
TERM mlterm
|
||||
TERM putty
|
||||
TERM rxvt
|
||||
TERM rxvt-256color
|
||||
TERM rxvt-cygwin
|
||||
TERM rxvt-cygwin-native
|
||||
TERM rxvt-unicode
|
||||
TERM rxvt-unicode256
|
||||
TERM rxvt-unicode-256color
|
||||
TERM screen
|
||||
TERM screen-256color
|
||||
TERM screen-256color-bce
|
||||
TERM screen-bce
|
||||
TERM screen-w
|
||||
TERM screen.linux
|
||||
TERM st
|
||||
TERM st-meta
|
||||
TERM st-256color
|
||||
TERM st-meta-256color
|
||||
TERM vt100
|
||||
TERM xterm
|
||||
TERM xterm-16color
|
||||
TERM xterm-256color
|
||||
TERM xterm-88color
|
||||
TERM xterm-color
|
||||
TERM xterm-debian
|
||||
TERM xterm-termite
|
||||
|
||||
## Documentation
|
||||
#
|
||||
# Attribute codes:
|
||||
# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
|
||||
# Text color codes:
|
||||
# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
|
||||
# Background color codes:
|
||||
# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
|
||||
#
|
||||
# Text 256 color coding:
|
||||
# 38;5;COLOR_NUMBER
|
||||
# Background 256 color coding:
|
||||
# 48;5;COLOR_NUMBER
|
||||
|
||||
# block device driver:
|
||||
BLK 48;5;108;38;5;223;01
|
||||
# file with capability:
|
||||
CAPABILITY 01;38;5;95
|
||||
# character device driver:
|
||||
CHR 48;5;108;38;5;223;01
|
||||
# directory:
|
||||
DIR 48;5;237;01;38;5;223
|
||||
# door:
|
||||
DOOR 48;5;237;38;5;180;01
|
||||
# This is for files with execute permission:
|
||||
EXEC 01;38;5;108
|
||||
# pipe:
|
||||
FIFO 48;5;237;38;5;180;01
|
||||
# regular file:
|
||||
#FILE 00
|
||||
# symbolic link:
|
||||
LINK 48;5;237;38;5;223
|
||||
# normal (nonfilename) text:
|
||||
#NORMAL 00
|
||||
# orphaned symbolic link:
|
||||
ORPHAN 48;5;237;38;5;187
|
||||
# directory that is other-writable (o+w) and not sticky:
|
||||
OTHER_WRITABLE 48;5;237;38;5;180
|
||||
# file that is setuid (u+s):
|
||||
SETUID 48;5;237;38;5;66
|
||||
# file that is setgid (g+s):
|
||||
SETGID 48;5;237;38;5;66
|
||||
# socket:
|
||||
SOCK 48;5;237;38;5;180;01
|
||||
# directory with the sticky bit set (+t) and not other-writable:
|
||||
STICKY 48;5;180;38;5;234
|
||||
# dir that is sticky and other-writable (+t,o+w):
|
||||
STICKY_OTHER_WRITABLE 48;5;180;38;5;234
|
||||
|
||||
# archives
|
||||
.7z 01;38;5;174
|
||||
.arj 01;38;5;174
|
||||
.bz2 01;38;5;174
|
||||
.bz 01;38;5;174
|
||||
.gz 01;38;5;174
|
||||
.rar 01;38;5;174
|
||||
.tar 01;38;5;174
|
||||
.tgz 01;38;5;174
|
||||
.tbz 01;38;5;174
|
||||
.tbz2 01;38;5;174
|
||||
.xz 01;38;5;174
|
||||
.zip 01;38;5;174
|
||||
|
||||
# packaged apps
|
||||
.apk 01;38;5;95
|
||||
.deb 01;38;5;174
|
||||
.jad 01;38;5;95
|
||||
.jar 01;38;5;95
|
||||
.rpm 01;38;5;174
|
||||
|
||||
# images|graphics
|
||||
.bmp 00;38;5;109
|
||||
.gif 00;38;5;109
|
||||
.ico 00;38;5;109
|
||||
.jpg 00;38;5;109
|
||||
.JPG 00;38;5;109
|
||||
.jpeg 00;38;5;109
|
||||
.png 00;38;5;109
|
||||
.svg 00;38;5;109
|
||||
.xbm 00;38;5;109
|
||||
.xpm 00;38;5;109
|
||||
|
||||
# audio formats
|
||||
.aac 00;38;5;116
|
||||
.au 00;38;5;116
|
||||
.flac 00;38;5;116
|
||||
.mid 00;38;5;116
|
||||
.midi 00;38;5;116
|
||||
.mka 00;38;5;116
|
||||
.mp3 00;38;5;116
|
||||
.mpc 00;38;5;116
|
||||
.ogg 00;38;5;116
|
||||
.ra 00;38;5;116
|
||||
.wav 00;38;5;116
|
||||
|
||||
# video formats
|
||||
.mov 00;38;5;66
|
||||
.mpg 00;38;5;66
|
||||
.mpeg 00;38;5;66
|
||||
.m2v 00;38;5;66
|
||||
.mkv 00;38;5;66
|
||||
.ogm 00;38;5;66
|
||||
.mp4 00;38;5;66
|
||||
.m4v 00;38;5;66
|
||||
.mp4v 00;38;5;66
|
||||
.vob 00;38;5;66
|
||||
.qt 00;38;5;66
|
||||
.nuv 00;38;5;66
|
||||
.wmv 00;38;5;66
|
||||
.asf 00;38;5;66
|
||||
.rm 00;38;5;66
|
||||
.rmvb 01;38;5;66
|
||||
.flc 00;38;5;66
|
||||
.avi 00;38;5;66
|
||||
.fli 00;38;5;66
|
||||
.flv 00;38;5;66
|
||||
.gl 00;38;5;66
|
||||
.m2ts 00;38;5;66
|
||||
.divx 00;38;5;66
|
||||
.webm 00;38;5;66
|
||||
|
||||
# shell
|
||||
.awk 00;38;5;151
|
||||
.bash 00;38;5;151
|
||||
.bat 00;38;5;151
|
||||
.BAT 00;38;5;151
|
||||
.sed 00;38;5;151
|
||||
.sh 00;38;5;151
|
||||
.zsh 00;38;5;151
|
||||
|
||||
# build
|
||||
*CMakeLists.txt 00;38;5;187
|
||||
.cabal 00;38;5;187
|
||||
*Makefile 00;38;5;187
|
||||
.mk 00;38;5;187
|
||||
.make 00;38;5;187
|
||||
|
||||
# source files
|
||||
.c 01;38;5;187
|
||||
.h 01;38;5;187
|
||||
.s 01;38;5;187
|
||||
.cs 01;38;5;187
|
||||
.java 01;38;5;187
|
||||
.scala 01;38;5;187
|
||||
.hs 01;38;5;187
|
||||
.py 01;38;5;187
|
||||
.rb 01;38;5;187
|
||||
.php 01;38;5;187
|
||||
.pl 01;38;5;187
|
||||
.vim 01;38;5;187
|
||||
.js 01;38;5;187
|
||||
.coffee 01;38;5;187
|
||||
.go 01;38;5;187
|
||||
.lisp 01;38;5;187
|
||||
.scm 01;38;5;187
|
||||
|
||||
# documents
|
||||
.txt 04;38;5;188
|
||||
.tex 04;38;5;188
|
||||
.html 04;38;5;188
|
||||
.xhtml 04;38;5;188
|
||||
.xml 04;38;5;188
|
||||
.md 04;38;5;188
|
||||
.mkd 04;38;5;188
|
||||
.markdown 04;38;5;188
|
||||
.org 04;38;5;188
|
||||
.pandoc 04;38;5;188
|
||||
.pdc 04;38;5;188
|
||||
.pdf 04;38;5;188
|
||||
|
||||
# Files of special interest
|
||||
*rc 04;38;5;180
|
||||
.conf 04;38;5;180
|
||||
*Dockerfile 04;38;5;180
|
||||
|
||||
# meta
|
||||
*README 04;38;5;187
|
||||
*LICENSE 04;38;5;187
|
||||
*AUTHORS 04;38;5;187
|
||||
|
||||
# version control
|
||||
.gitignore 00;38;5;248
|
||||
.gitmodules 00;38;5;248
|
||||
|
||||
# logs and backups
|
||||
.log 00;38;5;234
|
||||
.bak 00;38;5;234
|
||||
.aux 00;38;5;234
|
||||
.toc 00;38;5;234
|
||||
*~ 00;38;5;234
|
||||
*# 00;38;5;234
|
||||
.swp 00;38;5;234
|
||||
.tmp 00;38;5;234
|
||||
.temp 00;38;5;234
|
||||
.o 00;38;5;234
|
||||
.pyc 00;38;5;234
|
||||
.class 00;38;5;234
|
||||
.cache 00;38;5;234
|
||||
|
||||
# pacman files
|
||||
.pacnew 48;5;95;38;5;108
|
||||
.pacsave 48;5;95;38;5;108
|
||||
.pacorig 48;5;95;38;5;108
|
||||
*PKGBUILD 00;38;5;110
|
||||
|
||||
# rpm files
|
||||
.rpmsave 48;5;95;38;5;108
|
||||
.rpmorig 48;5;95;38;5;108
|
||||
.rpmnew 48;5;95;38;5;108
|
||||
.spec 00;38;5;110
|
30
roles/xmonad/files/dmenu/LICENSE
Normal file
30
roles/xmonad/files/dmenu/LICENSE
Normal file
@ -0,0 +1,30 @@
|
||||
MIT/X Consortium License
|
||||
|
||||
© 2006-2019 Anselm R Garbe <anselm@garbe.ca>
|
||||
© 2006-2008 Sander van Dijk <a.h.vandijk@gmail.com>
|
||||
© 2006-2007 Michał Janeczek <janeczek@gmail.com>
|
||||
© 2007 Kris Maglione <jg@suckless.org>
|
||||
© 2009 Gottox <gottox@s01.de>
|
||||
© 2009 Markus Schnalke <meillo@marmaro.de>
|
||||
© 2009 Evan Gates <evan.gates@gmail.com>
|
||||
© 2010-2012 Connor Lane Smith <cls@lubutu.com>
|
||||
© 2014-2020 Hiltjo Posthuma <hiltjo@codemadness.org>
|
||||
© 2015-2019 Quentin Rameau <quinq@fifth.space>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
64
roles/xmonad/files/dmenu/Makefile
Normal file
64
roles/xmonad/files/dmenu/Makefile
Normal file
@ -0,0 +1,64 @@
|
||||
# dmenu - dynamic menu
|
||||
# See LICENSE file for copyright and license details.
|
||||
|
||||
include config.mk
|
||||
|
||||
SRC = drw.c dmenu.c stest.c util.c
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
||||
all: options dmenu stest
|
||||
|
||||
options:
|
||||
@echo dmenu build options:
|
||||
@echo "CFLAGS = $(CFLAGS)"
|
||||
@echo "LDFLAGS = $(LDFLAGS)"
|
||||
@echo "CC = $(CC)"
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CFLAGS) $<
|
||||
|
||||
config.h:
|
||||
cp config.def.h $@
|
||||
|
||||
$(OBJ): arg.h config.h config.mk drw.h
|
||||
|
||||
dmenu: dmenu.o drw.o util.o
|
||||
$(CC) -o $@ dmenu.o drw.o util.o $(LDFLAGS)
|
||||
|
||||
stest: stest.o
|
||||
$(CC) -o $@ stest.o $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f dmenu stest $(OBJ) dmenu-$(VERSION).tar.gz
|
||||
|
||||
dist: clean
|
||||
mkdir -p dmenu-$(VERSION)
|
||||
cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1\
|
||||
drw.h util.h dmenu_path dmenu_run stest.1 $(SRC)\
|
||||
dmenu-$(VERSION)
|
||||
tar -cf dmenu-$(VERSION).tar dmenu-$(VERSION)
|
||||
gzip dmenu-$(VERSION).tar
|
||||
rm -rf dmenu-$(VERSION)
|
||||
|
||||
install: all
|
||||
mkdir -p $(DESTDIR)$(PREFIX)/bin
|
||||
cp -f dmenu dmenu_path dmenu_run stest $(DESTDIR)$(PREFIX)/bin
|
||||
chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu
|
||||
chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_path
|
||||
chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_run
|
||||
chmod 755 $(DESTDIR)$(PREFIX)/bin/stest
|
||||
mkdir -p $(DESTDIR)$(MANPREFIX)/man1
|
||||
sed "s/VERSION/$(VERSION)/g" < dmenu.1 > $(DESTDIR)$(MANPREFIX)/man1/dmenu.1
|
||||
sed "s/VERSION/$(VERSION)/g" < stest.1 > $(DESTDIR)$(MANPREFIX)/man1/stest.1
|
||||
chmod 644 $(DESTDIR)$(MANPREFIX)/man1/dmenu.1
|
||||
chmod 644 $(DESTDIR)$(MANPREFIX)/man1/stest.1
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)$(PREFIX)/bin/dmenu\
|
||||
$(DESTDIR)$(PREFIX)/bin/dmenu_path\
|
||||
$(DESTDIR)$(PREFIX)/bin/dmenu_run\
|
||||
$(DESTDIR)$(PREFIX)/bin/stest\
|
||||
$(DESTDIR)$(MANPREFIX)/man1/dmenu.1\
|
||||
$(DESTDIR)$(MANPREFIX)/man1/stest.1
|
||||
|
||||
.PHONY: all options clean dist install uninstall
|
24
roles/xmonad/files/dmenu/README
Normal file
24
roles/xmonad/files/dmenu/README
Normal file
@ -0,0 +1,24 @@
|
||||
dmenu - dynamic menu
|
||||
====================
|
||||
dmenu is an efficient dynamic menu for X.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
In order to build dmenu you need the Xlib header files.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
Edit config.mk to match your local setup (dmenu is installed into
|
||||
the /usr/local namespace by default).
|
||||
|
||||
Afterwards enter the following command to build and install dmenu
|
||||
(if necessary as root):
|
||||
|
||||
make clean install
|
||||
|
||||
|
||||
Running dmenu
|
||||
-------------
|
||||
See the man page for details.
|
49
roles/xmonad/files/dmenu/arg.h
Normal file
49
roles/xmonad/files/dmenu/arg.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copy me if you can.
|
||||
* by 20h
|
||||
*/
|
||||
|
||||
#ifndef ARG_H__
|
||||
#define ARG_H__
|
||||
|
||||
extern char *argv0;
|
||||
|
||||
/* use main(int argc, char *argv[]) */
|
||||
#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\
|
||||
argv[0] && argv[0][0] == '-'\
|
||||
&& argv[0][1];\
|
||||
argc--, argv++) {\
|
||||
char argc_;\
|
||||
char **argv_;\
|
||||
int brk_;\
|
||||
if (argv[0][1] == '-' && argv[0][2] == '\0') {\
|
||||
argv++;\
|
||||
argc--;\
|
||||
break;\
|
||||
}\
|
||||
for (brk_ = 0, argv[0]++, argv_ = argv;\
|
||||
argv[0][0] && !brk_;\
|
||||
argv[0]++) {\
|
||||
if (argv_ != argv)\
|
||||
break;\
|
||||
argc_ = argv[0][0];\
|
||||
switch (argc_)
|
||||
|
||||
#define ARGEND }\
|
||||
}
|
||||
|
||||
#define ARGC() argc_
|
||||
|
||||
#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\
|
||||
((x), abort(), (char *)0) :\
|
||||
(brk_ = 1, (argv[0][1] != '\0')?\
|
||||
(&argv[0][1]) :\
|
||||
(argc--, argv++, argv[0])))
|
||||
|
||||
#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\
|
||||
(char *)0 :\
|
||||
(brk_ = 1, (argv[0][1] != '\0')?\
|
||||
(&argv[0][1]) :\
|
||||
(argc--, argv++, argv[0])))
|
||||
|
||||
#endif
|
29
roles/xmonad/files/dmenu/config.def.h
Normal file
29
roles/xmonad/files/dmenu/config.def.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
/* Default settings; can be overriden by command line. */
|
||||
|
||||
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
|
||||
static int centered = 0; /* -c option; centers dmenu on screen */
|
||||
static int min_width = 500; /* minimum width when centered */
|
||||
static int colorprompt = 1; /* -p option; if 1, prompt uses SchemeSel, otherwise SchemeNorm */
|
||||
/* -fn option overrides fonts[0]; default X11 font or font set */
|
||||
static const char *fonts[] = {
|
||||
"monospace:size=10"
|
||||
};
|
||||
static const char *prompt = NULL; /* -p option; prompt to the left of input field */
|
||||
static const char *colors[SchemeLast][2] = {
|
||||
/* fg bg */
|
||||
[SchemeNorm] = { "#bbbbbb", "#222222" },
|
||||
[SchemeSel] = { "#eeeeee", "#005577" },
|
||||
[SchemeOut] = { "#000000", "#00ffff" },
|
||||
};
|
||||
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
|
||||
static unsigned int lines = 0;
|
||||
|
||||
/*
|
||||
* Characters not considered part of a word while deleting words
|
||||
* for example: " /?\"&[]"
|
||||
*/
|
||||
static const char worddelimiters[] = " ";
|
||||
|
||||
/* Size of the window border */
|
||||
static unsigned int border_width = 0;
|
29
roles/xmonad/files/dmenu/config.h
Normal file
29
roles/xmonad/files/dmenu/config.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
/* Default settings; can be overriden by command line. */
|
||||
|
||||
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
|
||||
static int centered = 1; /* -c option; centers dmenu on screen */
|
||||
static int min_width = 500; /* minimum width when centered */
|
||||
static int colorprompt = 1; /* -p option; if 1, prompt uses SchemeSel, otherwise SchemeNorm */
|
||||
/* -fn option overrides fonts[0]; default X11 font or font set */
|
||||
static const char *fonts[] = {
|
||||
"Iosevka:pixelsize=12:antialias=true:autohint=true"
|
||||
};
|
||||
static const char *prompt = NULL; /* -p option; prompt to the left of input field */
|
||||
static const char *colors[SchemeLast][2] = {
|
||||
/* fg bg */
|
||||
[SchemeNorm] = { "#dcdccc", "#434443" },
|
||||
[SchemeSel] = { "#333333", "#dca3a3" },
|
||||
[SchemeOut] = { "#dca3a3", "#434443" },
|
||||
};
|
||||
/* -l option; if nonzero, dmenu uses vertical list with given number of lines */
|
||||
static unsigned int lines = 10;
|
||||
|
||||
/*
|
||||
* Characters not considered part of a word while deleting words
|
||||
* for example: " /?\"&[]"
|
||||
*/
|
||||
static const char worddelimiters[] = " ";
|
||||
|
||||
/* Size of the window border */
|
||||
static unsigned int border_width = 2;
|
31
roles/xmonad/files/dmenu/config.mk
Normal file
31
roles/xmonad/files/dmenu/config.mk
Normal file
@ -0,0 +1,31 @@
|
||||
# dmenu version
|
||||
VERSION = 5.0
|
||||
|
||||
# paths
|
||||
PREFIX = /usr/local
|
||||
MANPREFIX = $(PREFIX)/share/man
|
||||
|
||||
X11INC = /usr/X11R6/include
|
||||
X11LIB = /usr/X11R6/lib
|
||||
|
||||
# Xinerama, comment if you don't want it
|
||||
XINERAMALIBS = -lXinerama
|
||||
XINERAMAFLAGS = -DXINERAMA
|
||||
|
||||
# freetype
|
||||
FREETYPELIBS = -lfontconfig -lXft
|
||||
FREETYPEINC = /usr/include/freetype2
|
||||
# OpenBSD (uncomment)
|
||||
#FREETYPEINC = $(X11INC)/freetype2
|
||||
|
||||
# includes and libs
|
||||
INCS = -I$(X11INC) -I$(FREETYPEINC)
|
||||
LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS)
|
||||
|
||||
# flags
|
||||
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS)
|
||||
CFLAGS = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS)
|
||||
LDFLAGS = $(LIBS)
|
||||
|
||||
# compiler and linker
|
||||
CC = cc
|
197
roles/xmonad/files/dmenu/dmenu.1
Normal file
197
roles/xmonad/files/dmenu/dmenu.1
Normal file
@ -0,0 +1,197 @@
|
||||
.TH DMENU 1 dmenu\-VERSION
|
||||
.SH NAME
|
||||
dmenu \- dynamic menu
|
||||
.SH SYNOPSIS
|
||||
.B dmenu
|
||||
.RB [ \-bfiv ]
|
||||
.RB [ \-l
|
||||
.IR lines ]
|
||||
.RB [ \-m
|
||||
.IR monitor ]
|
||||
.RB [ \-p
|
||||
.IR prompt ]
|
||||
.RB [ \-fn
|
||||
.IR font ]
|
||||
.RB [ \-nb
|
||||
.IR color ]
|
||||
.RB [ \-nf
|
||||
.IR color ]
|
||||
.RB [ \-sb
|
||||
.IR color ]
|
||||
.RB [ \-sf
|
||||
.IR color ]
|
||||
.RB [ \-w
|
||||
.IR windowid ]
|
||||
.P
|
||||
.BR dmenu_run " ..."
|
||||
.SH DESCRIPTION
|
||||
.B dmenu
|
||||
is a dynamic menu for X, which reads a list of newline\-separated items from
|
||||
stdin. When the user selects an item and presses Return, their choice is printed
|
||||
to stdout and dmenu terminates. Entering text will narrow the items to those
|
||||
matching the tokens in the input.
|
||||
.P
|
||||
.B dmenu_run
|
||||
is a script used by
|
||||
.IR dwm (1)
|
||||
which lists programs in the user's $PATH and runs the result in their $SHELL.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-b
|
||||
dmenu appears at the bottom of the screen.
|
||||
.TP
|
||||
.B \-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.
|
||||
.TP
|
||||
.B \-i
|
||||
dmenu matches menu items case insensitively.
|
||||
.TP
|
||||
.BI \-l " lines"
|
||||
dmenu lists items vertically, with the given number of lines.
|
||||
.TP
|
||||
.BI \-m " monitor"
|
||||
dmenu is displayed on the monitor number supplied. Monitor numbers are starting
|
||||
from 0.
|
||||
.TP
|
||||
.BI \-p " prompt"
|
||||
defines the prompt to be displayed to the left of the input field.
|
||||
.TP
|
||||
.BI \-fn " font"
|
||||
defines the font or font set used.
|
||||
.TP
|
||||
.BI \-nb " color"
|
||||
defines the normal background color.
|
||||
.IR #RGB ,
|
||||
.IR #RRGGBB ,
|
||||
and X color names are supported.
|
||||
.TP
|
||||
.BI \-nf " color"
|
||||
defines the normal foreground color.
|
||||
.TP
|
||||
.BI \-sb " color"
|
||||
defines the selected background color.
|
||||
.TP
|
||||
.BI \-sf " color"
|
||||
defines the selected foreground color.
|
||||
.TP
|
||||
.B \-v
|
||||
prints version information to stdout, then exits.
|
||||
.TP
|
||||
.BI \-w " windowid"
|
||||
embed into windowid.
|
||||
.SH USAGE
|
||||
dmenu is completely controlled by the keyboard. Items are selected using the
|
||||
arrow keys, page up, page down, home, and end.
|
||||
.TP
|
||||
.B Tab
|
||||
Copy the selected item to the input field.
|
||||
.TP
|
||||
.B Return
|
||||
Confirm selection. Prints the selected item to stdout and exits, returning
|
||||
success.
|
||||
.TP
|
||||
.B Ctrl-Return
|
||||
Confirm selection. Prints the selected item to stdout and continues.
|
||||
.TP
|
||||
.B Shift\-Return
|
||||
Confirm input. Prints the input text to stdout and exits, returning success.
|
||||
.TP
|
||||
.B Escape
|
||||
Exit without selecting an item, returning failure.
|
||||
.TP
|
||||
.B Ctrl-Left
|
||||
Move cursor to the start of the current word
|
||||
.TP
|
||||
.B Ctrl-Right
|
||||
Move cursor to the end of the current word
|
||||
.TP
|
||||
.B C\-a
|
||||
Home
|
||||
.TP
|
||||
.B C\-b
|
||||
Left
|
||||
.TP
|
||||
.B C\-c
|
||||
Escape
|
||||
.TP
|
||||
.B C\-d
|
||||
Delete
|
||||
.TP
|
||||
.B C\-e
|
||||
End
|
||||
.TP
|
||||
.B C\-f
|
||||
Right
|
||||
.TP
|
||||
.B C\-g
|
||||
Escape
|
||||
.TP
|
||||
.B C\-h
|
||||
Backspace
|
||||
.TP
|
||||
.B C\-i
|
||||
Tab
|
||||
.TP
|
||||
.B C\-j
|
||||
Return
|
||||
.TP
|
||||
.B C\-J
|
||||
Shift-Return
|
||||
.TP
|
||||
.B C\-k
|
||||
Delete line right
|
||||
.TP
|
||||
.B C\-m
|
||||
Return
|
||||
.TP
|
||||
.B C\-M
|
||||
Shift-Return
|
||||
.TP
|
||||
.B C\-n
|
||||
Down
|
||||
.TP
|
||||
.B C\-p
|
||||
Up
|
||||
.TP
|
||||
.B C\-u
|
||||
Delete line left
|
||||
.TP
|
||||
.B C\-w
|
||||
Delete word left
|
||||
.TP
|
||||
.B C\-y
|
||||
Paste from primary X selection
|
||||
.TP
|
||||
.B C\-Y
|
||||
Paste from X clipboard
|
||||
.TP
|
||||
.B M\-b
|
||||
Move cursor to the start of the current word
|
||||
.TP
|
||||
.B M\-f
|
||||
Move cursor to the end of the current word
|
||||
.TP
|
||||
.B M\-g
|
||||
Home
|
||||
.TP
|
||||
.B M\-G
|
||||
End
|
||||
.TP
|
||||
.B M\-h
|
||||
Up
|
||||
.TP
|
||||
.B M\-j
|
||||
Page down
|
||||
.TP
|
||||
.B M\-k
|
||||
Page up
|
||||
.TP
|
||||
.B M\-l
|
||||
Down
|
||||
.SH SEE ALSO
|
||||
.IR dwm (1),
|
||||
.IR stest (1)
|
801
roles/xmonad/files/dmenu/dmenu.c
Normal file
801
roles/xmonad/files/dmenu/dmenu.c
Normal file
@ -0,0 +1,801 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
#include <ctype.h>
|
||||
#include <locale.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xutil.h>
|
||||
#ifdef XINERAMA
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
#endif
|
||||
#include <X11/Xft/Xft.h>
|
||||
|
||||
#include "drw.h"
|
||||
#include "util.h"
|
||||
|
||||
/* macros */
|
||||
#define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \
|
||||
* MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org)))
|
||||
#define LENGTH(X) (sizeof X / sizeof X[0])
|
||||
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
|
||||
|
||||
/* enums */
|
||||
enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
|
||||
|
||||
struct item {
|
||||
char *text;
|
||||
struct item *left, *right;
|
||||
int out;
|
||||
};
|
||||
|
||||
static char text[BUFSIZ] = "";
|
||||
static char *embed;
|
||||
static int bh, mw, mh;
|
||||
static int inputw = 0, promptw;
|
||||
static int lrpad; /* sum of left and right padding */
|
||||
static size_t cursor;
|
||||
static struct item *items = NULL;
|
||||
static struct item *matches, *matchend;
|
||||
static struct item *prev, *curr, *next, *sel;
|
||||
static int mon = -1, screen;
|
||||
|
||||
static Atom clip, utf8;
|
||||
static Display *dpy;
|
||||
static Window root, parentwin, win;
|
||||
static XIC xic;
|
||||
|
||||
static Drw *drw;
|
||||
static Clr *scheme[SchemeLast];
|
||||
|
||||
#include "config.h"
|
||||
|
||||
static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
|
||||
static char *(*fstrstr)(const char *, const char *) = strstr;
|
||||
|
||||
static void
|
||||
appenditem(struct item *item, struct item **list, struct item **last)
|
||||
{
|
||||
if (*last)
|
||||
(*last)->right = item;
|
||||
else
|
||||
*list = item;
|
||||
|
||||
item->left = *last;
|
||||
item->right = NULL;
|
||||
*last = item;
|
||||
}
|
||||
|
||||
static void
|
||||
calcoffsets(void)
|
||||
{
|
||||
int i, n;
|
||||
|
||||
if (lines > 0)
|
||||
n = lines * bh;
|
||||
else
|
||||
n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">"));
|
||||
/* calculate which items will begin the next page and previous page */
|
||||
for (i = 0, next = curr; next; next = next->right)
|
||||
if ((i += (lines > 0) ? bh : MIN(TEXTW(next->text), n)) > n)
|
||||
break;
|
||||
for (i = 0, prev = curr; prev && prev->left; prev = prev->left)
|
||||
if ((i += (lines > 0) ? bh : MIN(TEXTW(prev->left->text), n)) > n)
|
||||
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)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
XUngrabKey(dpy, AnyKey, AnyModifier, root);
|
||||
for (i = 0; i < SchemeLast; i++)
|
||||
free(scheme[i]);
|
||||
drw_free(drw);
|
||||
XSync(dpy, False);
|
||||
XCloseDisplay(dpy);
|
||||
}
|
||||
|
||||
static char *
|
||||
cistrstr(const char *s, const char *sub)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
for (len = strlen(sub); *s; s++)
|
||||
if (!strncasecmp(s, sub, len))
|
||||
return (char *)s;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
drawitem(struct item *item, int x, int y, int w)
|
||||
{
|
||||
if (item == sel)
|
||||
drw_setscheme(drw, scheme[SchemeSel]);
|
||||
else if (item->out)
|
||||
drw_setscheme(drw, scheme[SchemeOut]);
|
||||
else
|
||||
drw_setscheme(drw, scheme[SchemeNorm]);
|
||||
|
||||
return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
drawmenu(void)
|
||||
{
|
||||
unsigned int curpos;
|
||||
struct item *item;
|
||||
int x = 0, y = 0, w;
|
||||
|
||||
drw_setscheme(drw, scheme[SchemeNorm]);
|
||||
drw_rect(drw, 0, 0, mw, mh, 1, 1);
|
||||
|
||||
if (prompt && *prompt) {
|
||||
if (colorprompt)
|
||||
drw_setscheme(drw, scheme[SchemeSel]);
|
||||
x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0);
|
||||
}
|
||||
/* draw input field */
|
||||
w = (lines > 0 || !matches) ? mw - x : inputw;
|
||||
drw_setscheme(drw, scheme[SchemeNorm]);
|
||||
drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0);
|
||||
|
||||
curpos = TEXTW(text) - TEXTW(&text[cursor]);
|
||||
if ((curpos += lrpad / 2 - 1) < w) {
|
||||
drw_setscheme(drw, scheme[SchemeNorm]);
|
||||
drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0);
|
||||
}
|
||||
|
||||
if (lines > 0) {
|
||||
/* draw vertical list */
|
||||
for (item = curr; item != next; item = item->right)
|
||||
drawitem(item, 0, y += bh, mw - x);
|
||||
} else if (matches) {
|
||||
/* draw horizontal list */
|
||||
x += inputw;
|
||||
w = TEXTW("<");
|
||||
if (curr->left) {
|
||||
drw_setscheme(drw, scheme[SchemeNorm]);
|
||||
drw_text(drw, x, 0, w, bh, lrpad / 2, "<", 0);
|
||||
}
|
||||
x += w;
|
||||
for (item = curr; item != next; item = item->right)
|
||||
x = drawitem(item, x, 0, MIN(TEXTW(item->text), mw - x - TEXTW(">")));
|
||||
if (next) {
|
||||
w = TEXTW(">");
|
||||
drw_setscheme(drw, scheme[SchemeNorm]);
|
||||
drw_text(drw, mw - w, 0, w, bh, lrpad / 2, ">", 0);
|
||||
}
|
||||
}
|
||||
drw_map(drw, win, 0, 0, mw, mh);
|
||||
}
|
||||
|
||||
static void
|
||||
grabfocus(void)
|
||||
{
|
||||
struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 };
|
||||
Window focuswin;
|
||||
int i, revertwin;
|
||||
|
||||
for (i = 0; i < 100; ++i) {
|
||||
XGetInputFocus(dpy, &focuswin, &revertwin);
|
||||
if (focuswin == win)
|
||||
return;
|
||||
XSetInputFocus(dpy, win, RevertToParent, CurrentTime);
|
||||
nanosleep(&ts, NULL);
|
||||
}
|
||||
die("cannot grab focus");
|
||||
}
|
||||
|
||||
static void
|
||||
grabkeyboard(void)
|
||||
{
|
||||
struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 };
|
||||
int i;
|
||||
|
||||
if (embed)
|
||||
return;
|
||||
/* try to grab keyboard, we may have to wait for another process to ungrab */
|
||||
for (i = 0; i < 1000; i++) {
|
||||
if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync,
|
||||
GrabModeAsync, CurrentTime) == GrabSuccess)
|
||||
return;
|
||||
nanosleep(&ts, NULL);
|
||||
}
|
||||
die("cannot grab keyboard");
|
||||
}
|
||||
|
||||
static void
|
||||
match(void)
|
||||
{
|
||||
static char **tokv = NULL;
|
||||
static int tokn = 0;
|
||||
|
||||
char buf[sizeof text], *s;
|
||||
int i, tokc = 0;
|
||||
size_t len, textsize;
|
||||
struct item *item, *lprefix, *lsubstr, *prefixend, *substrend;
|
||||
|
||||
strcpy(buf, text);
|
||||
/* separate input text into tokens to be matched individually */
|
||||
for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " "))
|
||||
if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv)))
|
||||
die("cannot realloc %u bytes:", tokn * sizeof *tokv);
|
||||
len = tokc ? strlen(tokv[0]) : 0;
|
||||
|
||||
matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL;
|
||||
textsize = strlen(text) + 1;
|
||||
for (item = items; item && item->text; item++) {
|
||||
for (i = 0; i < tokc; i++)
|
||||
if (!fstrstr(item->text, tokv[i]))
|
||||
break;
|
||||
if (i != tokc) /* not all tokens match */
|
||||
continue;
|
||||
/* exact matches go first, then prefixes, then substrings */
|
||||
if (!tokc || !fstrncmp(text, item->text, textsize))
|
||||
appenditem(item, &matches, &matchend);
|
||||
else if (!fstrncmp(tokv[0], item->text, len))
|
||||
appenditem(item, &lprefix, &prefixend);
|
||||
else
|
||||
appenditem(item, &lsubstr, &substrend);
|
||||
}
|
||||
if (lprefix) {
|
||||
if (matches) {
|
||||
matchend->right = lprefix;
|
||||
lprefix->left = matchend;
|
||||
} else
|
||||
matches = lprefix;
|
||||
matchend = prefixend;
|
||||
}
|
||||
if (lsubstr) {
|
||||
if (matches) {
|
||||
matchend->right = lsubstr;
|
||||
lsubstr->left = matchend;
|
||||
} else
|
||||
matches = lsubstr;
|
||||
matchend = substrend;
|
||||
}
|
||||
curr = sel = matches;
|
||||
calcoffsets();
|
||||
}
|
||||
|
||||
static void
|
||||
insert(const char *str, ssize_t n)
|
||||
{
|
||||
if (strlen(text) + n > sizeof text - 1)
|
||||
return;
|
||||
/* move existing text out of the way, insert new text, and update cursor */
|
||||
memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0));
|
||||
if (n > 0)
|
||||
memcpy(&text[cursor], str, n);
|
||||
cursor += n;
|
||||
match();
|
||||
}
|
||||
|
||||
static size_t
|
||||
nextrune(int inc)
|
||||
{
|
||||
ssize_t n;
|
||||
|
||||
/* return location of next utf8 rune in the given direction (+1 or -1) */
|
||||
for (n = cursor + inc; n + inc >= 0 && (text[n] & 0xc0) == 0x80; n += inc)
|
||||
;
|
||||
return n;
|
||||
}
|
||||
|
||||
static void
|
||||
movewordedge(int dir)
|
||||
{
|
||||
if (dir < 0) { /* move cursor to the start of the word*/
|
||||
while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)]))
|
||||
cursor = nextrune(-1);
|
||||
while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)]))
|
||||
cursor = nextrune(-1);
|
||||
} else { /* move cursor to the end of the word */
|
||||
while (text[cursor] && strchr(worddelimiters, text[cursor]))
|
||||
cursor = nextrune(+1);
|
||||
while (text[cursor] && !strchr(worddelimiters, text[cursor]))
|
||||
cursor = nextrune(+1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
keypress(XKeyEvent *ev)
|
||||
{
|
||||
char buf[32];
|
||||
int len;
|
||||
KeySym ksym;
|
||||
Status status;
|
||||
|
||||
len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status);
|
||||
switch (status) {
|
||||
default: /* XLookupNone, XBufferOverflow */
|
||||
return;
|
||||
case XLookupChars:
|
||||
goto insert;
|
||||
case XLookupKeySym:
|
||||
case XLookupBoth:
|
||||
break;
|
||||
}
|
||||
|
||||
if (ev->state & ControlMask) {
|
||||
switch(ksym) {
|
||||
case XK_a: ksym = XK_Home; break;
|
||||
case XK_b: ksym = XK_Left; break;
|
||||
case XK_c: ksym = XK_Escape; break;
|
||||
case XK_d: ksym = XK_Delete; break;
|
||||
case XK_e: ksym = XK_End; break;
|
||||
case XK_f: ksym = XK_Right; break;
|
||||
case XK_g: ksym = XK_Escape; break;
|
||||
case XK_h: ksym = XK_BackSpace; break;
|
||||
case XK_i: ksym = XK_Tab; break;
|
||||
case XK_j: /* fallthrough */
|
||||
case XK_J: /* fallthrough */
|
||||
case XK_m: /* fallthrough */
|
||||
case XK_M: ksym = XK_Return; ev->state &= ~ControlMask; break;
|
||||
case XK_n: ksym = XK_Down; break;
|
||||
case XK_p: ksym = XK_Up; break;
|
||||
|
||||
case XK_k: /* delete right */
|
||||
text[cursor] = '\0';
|
||||
match();
|
||||
break;
|
||||
case XK_u: /* delete left */
|
||||
insert(NULL, 0 - cursor);
|
||||
break;
|
||||
case XK_w: /* delete word */
|
||||
while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)]))
|
||||
insert(NULL, nextrune(-1) - cursor);
|
||||
while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)]))
|
||||
insert(NULL, nextrune(-1) - cursor);
|
||||
break;
|
||||
case XK_y: /* paste selection */
|
||||
case XK_Y:
|
||||
XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
|
||||
utf8, utf8, win, CurrentTime);
|
||||
return;
|
||||
case XK_Left:
|
||||
movewordedge(-1);
|
||||
goto draw;
|
||||
case XK_Right:
|
||||
movewordedge(+1);
|
||||
goto draw;
|
||||
case XK_Return:
|
||||
case XK_KP_Enter:
|
||||
break;
|
||||
case XK_bracketleft:
|
||||
cleanup();
|
||||
exit(1);
|
||||
default:
|
||||
return;
|
||||
}
|
||||
} else if (ev->state & Mod1Mask) {
|
||||
switch(ksym) {
|
||||
case XK_b:
|
||||
movewordedge(-1);
|
||||
goto draw;
|
||||
case XK_f:
|
||||
movewordedge(+1);
|
||||
goto draw;
|
||||
case XK_g: ksym = XK_Home; break;
|
||||
case XK_G: ksym = XK_End; break;
|
||||
case XK_h: ksym = XK_Up; break;
|
||||
case XK_j: ksym = XK_Next; break;
|
||||
case XK_k: ksym = XK_Prior; break;
|
||||
case XK_l: ksym = XK_Down; break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch(ksym) {
|
||||
default:
|
||||
insert:
|
||||
if (!iscntrl(*buf))
|
||||
insert(buf, len);
|
||||
break;
|
||||
case XK_Delete:
|
||||
if (text[cursor] == '\0')
|
||||
return;
|
||||
cursor = nextrune(+1);
|
||||
/* fallthrough */
|
||||
case XK_BackSpace:
|
||||
if (cursor == 0)
|
||||
return;
|
||||
insert(NULL, nextrune(-1) - cursor);
|
||||
break;
|
||||
case XK_End:
|
||||
if (text[cursor] != '\0') {
|
||||
cursor = strlen(text);
|
||||
break;
|
||||
}
|
||||
if (next) {
|
||||
/* jump to end of list and position items in reverse */
|
||||
curr = matchend;
|
||||
calcoffsets();
|
||||
curr = prev;
|
||||
calcoffsets();
|
||||
while (next && (curr = curr->right))
|
||||
calcoffsets();
|
||||
}
|
||||
sel = matchend;
|
||||
break;
|
||||
case XK_Escape:
|
||||
cleanup();
|
||||
exit(1);
|
||||
case XK_Home:
|
||||
if (sel == matches) {
|
||||
cursor = 0;
|
||||
break;
|
||||
}
|
||||
sel = curr = matches;
|
||||
calcoffsets();
|
||||
break;
|
||||
case XK_Left:
|
||||
if (cursor > 0 && (!sel || !sel->left || lines > 0)) {
|
||||
cursor = nextrune(-1);
|
||||
break;
|
||||
}
|
||||
if (lines > 0)
|
||||
return;
|
||||
/* fallthrough */
|
||||
case XK_Prior:
|
||||
if (sel && sel->left && (sel = sel->left)->right == curr) {
|
||||
curr = prev;
|
||||
calcoffsets();
|
||||
}
|
||||
break;
|
||||
case XK_Down:
|
||||
if (!next)
|
||||
return;
|
||||
sel = curr = next;
|
||||
calcoffsets();
|
||||
break;
|
||||
case XK_Up:
|
||||
if (!prev)
|
||||
return;
|
||||
sel = curr = prev;
|
||||
calcoffsets();
|
||||
break;
|
||||
case XK_Return:
|
||||
case XK_KP_Enter:
|
||||
puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
|
||||
if (!(ev->state & ControlMask)) {
|
||||
cleanup();
|
||||
exit(0);
|
||||
}
|
||||
if (sel)
|
||||
sel->out = 1;
|
||||
break;
|
||||
case XK_Right:
|
||||
if (text[cursor] != '\0') {
|
||||
cursor = nextrune(+1);
|
||||
break;
|
||||
}
|
||||
if (lines > 0)
|
||||
return;
|
||||
/* fallthrough */
|
||||
case XK_Next:
|
||||
if (sel && sel->right && (sel = sel->right) == next) {
|
||||
curr = next;
|
||||
calcoffsets();
|
||||
}
|
||||
break;
|
||||
case XK_Tab:
|
||||
if (!sel)
|
||||
return;
|
||||
strncpy(text, sel->text, sizeof text - 1);
|
||||
text[sizeof text - 1] = '\0';
|
||||
cursor = strlen(text);
|
||||
match();
|
||||
break;
|
||||
}
|
||||
|
||||
draw:
|
||||
drawmenu();
|
||||
}
|
||||
|
||||
static void
|
||||
paste(void)
|
||||
{
|
||||
char *p, *q;
|
||||
int di;
|
||||
unsigned long dl;
|
||||
Atom da;
|
||||
|
||||
/* we have been given the current selection, now insert it into input */
|
||||
if (XGetWindowProperty(dpy, win, utf8, 0, (sizeof text / 4) + 1, False,
|
||||
utf8, &da, &di, &dl, &dl, (unsigned char **)&p)
|
||||
== Success && p) {
|
||||
insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p));
|
||||
XFree(p);
|
||||
}
|
||||
drawmenu();
|
||||
}
|
||||
|
||||
static void
|
||||
readstdin(void)
|
||||
{
|
||||
char buf[sizeof text], *p;
|
||||
size_t i, imax = 0, size = 0;
|
||||
unsigned int tmpmax = 0;
|
||||
|
||||
/* read each line from stdin and add it to the item list */
|
||||
for (i = 0; fgets(buf, sizeof buf, stdin); i++) {
|
||||
if (i + 1 >= size / sizeof *items)
|
||||
if (!(items = realloc(items, (size += BUFSIZ))))
|
||||
die("cannot realloc %u bytes:", size);
|
||||
if ((p = strchr(buf, '\n')))
|
||||
*p = '\0';
|
||||
if (!(items[i].text = strdup(buf)))
|
||||
die("cannot strdup %u bytes:", strlen(buf) + 1);
|
||||
items[i].out = 0;
|
||||
drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL);
|
||||
if (tmpmax > inputw) {
|
||||
inputw = tmpmax;
|
||||
imax = i;
|
||||
}
|
||||
}
|
||||
if (items)
|
||||
items[i].text = NULL;
|
||||
inputw = items ? TEXTW(items[imax].text) : 0;
|
||||
lines = MIN(lines, i);
|
||||
}
|
||||
|
||||
static void
|
||||
run(void)
|
||||
{
|
||||
XEvent ev;
|
||||
|
||||
while (!XNextEvent(dpy, &ev)) {
|
||||
if (XFilterEvent(&ev, win))
|
||||
continue;
|
||||
switch(ev.type) {
|
||||
case DestroyNotify:
|
||||
if (ev.xdestroywindow.window != win)
|
||||
break;
|
||||
cleanup();
|
||||
exit(1);
|
||||
case Expose:
|
||||
if (ev.xexpose.count == 0)
|
||||
drw_map(drw, win, 0, 0, mw, mh);
|
||||
break;
|
||||
case FocusIn:
|
||||
/* regrab focus from parent window */
|
||||
if (ev.xfocus.window != win)
|
||||
grabfocus();
|
||||
break;
|
||||
case KeyPress:
|
||||
keypress(&ev.xkey);
|
||||
break;
|
||||
case SelectionNotify:
|
||||
if (ev.xselection.property == utf8)
|
||||
paste();
|
||||
break;
|
||||
case VisibilityNotify:
|
||||
if (ev.xvisibility.state != VisibilityUnobscured)
|
||||
XRaiseWindow(dpy, win);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
setup(void)
|
||||
{
|
||||
int x, y, i, j;
|
||||
unsigned int du;
|
||||
XSetWindowAttributes swa;
|
||||
XIM xim;
|
||||
Window w, dw, *dws;
|
||||
XWindowAttributes wa;
|
||||
XClassHint ch = {"dmenu", "dmenu"};
|
||||
#ifdef XINERAMA
|
||||
XineramaScreenInfo *info;
|
||||
Window pw;
|
||||
int a, di, n, area = 0;
|
||||
#endif
|
||||
/* init appearance */
|
||||
for (j = 0; j < SchemeLast; j++)
|
||||
scheme[j] = drw_scm_create(drw, colors[j], 2);
|
||||
|
||||
clip = XInternAtom(dpy, "CLIPBOARD", False);
|
||||
utf8 = XInternAtom(dpy, "UTF8_STRING", False);
|
||||
|
||||
/* calculate menu geometry */
|
||||
bh = drw->fonts->h + 2;
|
||||
lines = MAX(lines, 0);
|
||||
mh = (lines + 1) * bh;
|
||||
promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
|
||||
#ifdef XINERAMA
|
||||
i = 0;
|
||||
if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
|
||||
XGetInputFocus(dpy, &w, &di);
|
||||
if (mon >= 0 && mon < n)
|
||||
i = mon;
|
||||
else if (w != root && w != PointerRoot && w != None) {
|
||||
/* find top-level window containing current input focus */
|
||||
do {
|
||||
if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws)
|
||||
XFree(dws);
|
||||
} while (w != root && w != pw);
|
||||
/* find xinerama screen with which the window intersects most */
|
||||
if (XGetWindowAttributes(dpy, pw, &wa))
|
||||
for (j = 0; j < n; j++)
|
||||
if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) {
|
||||
area = a;
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
/* no focused window is on screen, so use pointer location instead */
|
||||
if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du))
|
||||
for (i = 0; i < n; i++)
|
||||
if (INTERSECT(x, y, 1, 1, info[i]))
|
||||
break;
|
||||
|
||||
if (centered) {
|
||||
mw = MIN(MAX(max_textw() + promptw, min_width), info[i].width);
|
||||
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
|
||||
{
|
||||
if (!XGetWindowAttributes(dpy, parentwin, &wa))
|
||||
die("could not get embedding window attributes: 0x%lx",
|
||||
parentwin);
|
||||
|
||||
if (centered) {
|
||||
mw = MIN(MAX(max_textw() + promptw, min_width), wa.width);
|
||||
x = (wa.width - mw) / 2;
|
||||
y = (wa.height - mh) / 2;
|
||||
} else {
|
||||
x = 0;
|
||||
y = topbar ? 0 : wa.height - mh;
|
||||
mw = wa.width;
|
||||
}
|
||||
}
|
||||
inputw = MIN(inputw, mw/3);
|
||||
match();
|
||||
|
||||
/* create menu window */
|
||||
swa.override_redirect = True;
|
||||
swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
|
||||
swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
|
||||
win = XCreateWindow(dpy, parentwin, x, y - (topbar ? 0 : border_width * 2), mw - border_width * 2, mh, border_width,
|
||||
CopyFromParent, CopyFromParent, CopyFromParent,
|
||||
CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
|
||||
if (border_width)
|
||||
XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel);
|
||||
XSetClassHint(dpy, win, &ch);
|
||||
|
||||
|
||||
/* input methods */
|
||||
if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL)
|
||||
die("XOpenIM failed: could not open input device");
|
||||
|
||||
xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
|
||||
XNClientWindow, win, XNFocusWindow, win, NULL);
|
||||
|
||||
XMapRaised(dpy, win);
|
||||
if (embed) {
|
||||
XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask);
|
||||
if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) {
|
||||
for (i = 0; i < du && dws[i] != win; ++i)
|
||||
XSelectInput(dpy, dws[i], FocusChangeMask);
|
||||
XFree(dws);
|
||||
}
|
||||
grabfocus();
|
||||
}
|
||||
drw_resize(drw, mw, mh);
|
||||
drawmenu();
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
|
||||
" [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
XWindowAttributes wa;
|
||||
int i, fast = 0;
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
/* these options take no arguments */
|
||||
if (!strcmp(argv[i], "-v")) { /* prints version information */
|
||||
puts("dmenu-"VERSION);
|
||||
exit(0);
|
||||
} else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */
|
||||
topbar = 0;
|
||||
else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */
|
||||
fast = 1;
|
||||
else if (!strcmp(argv[i], "-c")) /* centers dmenu on screen */
|
||||
centered = 1;
|
||||
else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
|
||||
fstrncmp = strncasecmp;
|
||||
fstrstr = cistrstr;
|
||||
} else if (i + 1 == argc)
|
||||
usage();
|
||||
/* these options take one argument */
|
||||
else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */
|
||||
lines = atoi(argv[++i]);
|
||||
else if (!strcmp(argv[i], "-m"))
|
||||
mon = atoi(argv[++i]);
|
||||
else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */
|
||||
prompt = argv[++i];
|
||||
else if (!strcmp(argv[i], "-fn")) /* font or font set */
|
||||
fonts[0] = argv[++i];
|
||||
else if (!strcmp(argv[i], "-nb")) /* normal background color */
|
||||
colors[SchemeNorm][ColBg] = argv[++i];
|
||||
else if (!strcmp(argv[i], "-nf")) /* normal foreground color */
|
||||
colors[SchemeNorm][ColFg] = argv[++i];
|
||||
else if (!strcmp(argv[i], "-sb")) /* selected background color */
|
||||
colors[SchemeSel][ColBg] = argv[++i];
|
||||
else if (!strcmp(argv[i], "-sf")) /* selected foreground color */
|
||||
colors[SchemeSel][ColFg] = argv[++i];
|
||||
else if (!strcmp(argv[i], "-w")) /* embedding window id */
|
||||
embed = argv[++i];
|
||||
else if (!strcmp(argv[i], "-bw"))
|
||||
border_width = atoi(argv[++i]); /* border width */
|
||||
else
|
||||
usage();
|
||||
|
||||
if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
|
||||
fputs("warning: no locale support\n", stderr);
|
||||
if (!(dpy = XOpenDisplay(NULL)))
|
||||
die("cannot open display");
|
||||
screen = DefaultScreen(dpy);
|
||||
root = RootWindow(dpy, screen);
|
||||
if (!embed || !(parentwin = strtol(embed, NULL, 0)))
|
||||
parentwin = root;
|
||||
if (!XGetWindowAttributes(dpy, parentwin, &wa))
|
||||
die("could not get embedding window attributes: 0x%lx",
|
||||
parentwin);
|
||||
drw = drw_create(dpy, screen, root, wa.width, wa.height);
|
||||
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
|
||||
die("no fonts could be loaded.");
|
||||
lrpad = drw->fonts->h;
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
if (pledge("stdio rpath", NULL) == -1)
|
||||
die("pledge");
|
||||
#endif
|
||||
|
||||
if (fast && !isatty(0)) {
|
||||
grabkeyboard();
|
||||
readstdin();
|
||||
} else {
|
||||
readstdin();
|
||||
grabkeyboard();
|
||||
}
|
||||
setup();
|
||||
run();
|
||||
|
||||
return 1; /* unreachable */
|
||||
}
|
13
roles/xmonad/files/dmenu/dmenu_path
Executable file
13
roles/xmonad/files/dmenu/dmenu_path
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
cachedir="${XDG_CACHE_HOME:-"$HOME/.cache"}"
|
||||
cache="$cachedir/dmenu_run"
|
||||
|
||||
[ ! -e "$cachedir" ] && mkdir -p "$cachedir"
|
||||
|
||||
IFS=:
|
||||
if stest -dqr -n "$cache" $PATH; then
|
||||
stest -flx $PATH | sort -u | tee "$cache"
|
||||
else
|
||||
cat "$cache"
|
||||
fi
|
2
roles/xmonad/files/dmenu/dmenu_run
Executable file
2
roles/xmonad/files/dmenu/dmenu_run
Executable file
@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} &
|
436
roles/xmonad/files/dmenu/drw.c
Normal file
436
roles/xmonad/files/dmenu/drw.c
Normal file
@ -0,0 +1,436 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xft/Xft.h>
|
||||
|
||||
#include "drw.h"
|
||||
#include "util.h"
|
||||
|
||||
#define UTF_INVALID 0xFFFD
|
||||
#define UTF_SIZ 4
|
||||
|
||||
static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
|
||||
static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
|
||||
static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
|
||||
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
|
||||
|
||||
static long
|
||||
utf8decodebyte(const char c, size_t *i)
|
||||
{
|
||||
for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
|
||||
if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
|
||||
return (unsigned char)c & ~utfmask[*i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t
|
||||
utf8validate(long *u, size_t i)
|
||||
{
|
||||
if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
|
||||
*u = UTF_INVALID;
|
||||
for (i = 1; *u > utfmax[i]; ++i)
|
||||
;
|
||||
return i;
|
||||
}
|
||||
|
||||
static size_t
|
||||
utf8decode(const char *c, long *u, size_t clen)
|
||||
{
|
||||
size_t i, j, len, type;
|
||||
long udecoded;
|
||||
|
||||
*u = UTF_INVALID;
|
||||
if (!clen)
|
||||
return 0;
|
||||
udecoded = utf8decodebyte(c[0], &len);
|
||||
if (!BETWEEN(len, 1, UTF_SIZ))
|
||||
return 1;
|
||||
for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
|
||||
udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
|
||||
if (type)
|
||||
return j;
|
||||
}
|
||||
if (j < len)
|
||||
return 0;
|
||||
*u = udecoded;
|
||||
utf8validate(u, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
Drw *
|
||||
drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
|
||||
{
|
||||
Drw *drw = ecalloc(1, sizeof(Drw));
|
||||
|
||||
drw->dpy = dpy;
|
||||
drw->screen = screen;
|
||||
drw->root = root;
|
||||
drw->w = w;
|
||||
drw->h = h;
|
||||
drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
|
||||
drw->gc = XCreateGC(dpy, root, 0, NULL);
|
||||
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
|
||||
return drw;
|
||||
}
|
||||
|
||||
void
|
||||
drw_resize(Drw *drw, unsigned int w, unsigned int h)
|
||||
{
|
||||
if (!drw)
|
||||
return;
|
||||
|
||||
drw->w = w;
|
||||
drw->h = h;
|
||||
if (drw->drawable)
|
||||
XFreePixmap(drw->dpy, drw->drawable);
|
||||
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
|
||||
}
|
||||
|
||||
void
|
||||
drw_free(Drw *drw)
|
||||
{
|
||||
XFreePixmap(drw->dpy, drw->drawable);
|
||||
XFreeGC(drw->dpy, drw->gc);
|
||||
drw_fontset_free(drw->fonts);
|
||||
free(drw);
|
||||
}
|
||||
|
||||
/* This function is an implementation detail. Library users should use
|
||||
* drw_fontset_create instead.
|
||||
*/
|
||||
static Fnt *
|
||||
xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
|
||||
{
|
||||
Fnt *font;
|
||||
XftFont *xfont = NULL;
|
||||
FcPattern *pattern = NULL;
|
||||
|
||||
if (fontname) {
|
||||
/* Using the pattern found at font->xfont->pattern does not yield the
|
||||
* same substitution results as using the pattern returned by
|
||||
* FcNameParse; using the latter results in the desired fallback
|
||||
* behaviour whereas the former just results in missing-character
|
||||
* rectangles being drawn, at least with some fonts. */
|
||||
if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
|
||||
fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
|
||||
return NULL;
|
||||
}
|
||||
if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
|
||||
fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
|
||||
XftFontClose(drw->dpy, xfont);
|
||||
return NULL;
|
||||
}
|
||||
} else if (fontpattern) {
|
||||
if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
|
||||
fprintf(stderr, "error, cannot load font from pattern.\n");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
die("no font specified.");
|
||||
}
|
||||
|
||||
/* Do not allow using color fonts. This is a workaround for a BadLength
|
||||
* error from Xft with color glyphs. Modelled on the Xterm workaround. See
|
||||
* https://bugzilla.redhat.com/show_bug.cgi?id=1498269
|
||||
* https://lists.suckless.org/dev/1701/30932.html
|
||||
* https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349
|
||||
* and lots more all over the internet.
|
||||
*/
|
||||
FcBool iscol;
|
||||
if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
|
||||
XftFontClose(drw->dpy, xfont);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
font = ecalloc(1, sizeof(Fnt));
|
||||
font->xfont = xfont;
|
||||
font->pattern = pattern;
|
||||
font->h = xfont->ascent + xfont->descent;
|
||||
font->dpy = drw->dpy;
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
static void
|
||||
xfont_free(Fnt *font)
|
||||
{
|
||||
if (!font)
|
||||
return;
|
||||
if (font->pattern)
|
||||
FcPatternDestroy(font->pattern);
|
||||
XftFontClose(font->dpy, font->xfont);
|
||||
free(font);
|
||||
}
|
||||
|
||||
Fnt*
|
||||
drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
|
||||
{
|
||||
Fnt *cur, *ret = NULL;
|
||||
size_t i;
|
||||
|
||||
if (!drw || !fonts)
|
||||
return NULL;
|
||||
|
||||
for (i = 1; i <= fontcount; i++) {
|
||||
if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
|
||||
cur->next = ret;
|
||||
ret = cur;
|
||||
}
|
||||
}
|
||||
return (drw->fonts = ret);
|
||||
}
|
||||
|
||||
void
|
||||
drw_fontset_free(Fnt *font)
|
||||
{
|
||||
if (font) {
|
||||
drw_fontset_free(font->next);
|
||||
xfont_free(font);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
|
||||
{
|
||||
if (!drw || !dest || !clrname)
|
||||
return;
|
||||
|
||||
if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
|
||||
DefaultColormap(drw->dpy, drw->screen),
|
||||
clrname, dest))
|
||||
die("error, cannot allocate color '%s'", clrname);
|
||||
}
|
||||
|
||||
/* Wrapper to create color schemes. The caller has to call free(3) on the
|
||||
* returned color scheme when done using it. */
|
||||
Clr *
|
||||
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
|
||||
{
|
||||
size_t i;
|
||||
Clr *ret;
|
||||
|
||||
/* need at least two colors for a scheme */
|
||||
if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < clrcount; i++)
|
||||
drw_clr_create(drw, &ret[i], clrnames[i]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
drw_setfontset(Drw *drw, Fnt *set)
|
||||
{
|
||||
if (drw)
|
||||
drw->fonts = set;
|
||||
}
|
||||
|
||||
void
|
||||
drw_setscheme(Drw *drw, Clr *scm)
|
||||
{
|
||||
if (drw)
|
||||
drw->scheme = scm;
|
||||
}
|
||||
|
||||
void
|
||||
drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
|
||||
{
|
||||
if (!drw || !drw->scheme)
|
||||
return;
|
||||
XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
|
||||
if (filled)
|
||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
||||
else
|
||||
XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
|
||||
}
|
||||
|
||||
int
|
||||
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
|
||||
{
|
||||
char buf[1024];
|
||||
int ty;
|
||||
unsigned int ew;
|
||||
XftDraw *d = NULL;
|
||||
Fnt *usedfont, *curfont, *nextfont;
|
||||
size_t i, len;
|
||||
int utf8strlen, utf8charlen, render = x || y || w || h;
|
||||
long utf8codepoint = 0;
|
||||
const char *utf8str;
|
||||
FcCharSet *fccharset;
|
||||
FcPattern *fcpattern;
|
||||
FcPattern *match;
|
||||
XftResult result;
|
||||
int charexists = 0;
|
||||
|
||||
if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
|
||||
return 0;
|
||||
|
||||
if (!render) {
|
||||
w = ~w;
|
||||
} else {
|
||||
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
|
||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
||||
d = XftDrawCreate(drw->dpy, drw->drawable,
|
||||
DefaultVisual(drw->dpy, drw->screen),
|
||||
DefaultColormap(drw->dpy, drw->screen));
|
||||
x += lpad;
|
||||
w -= lpad;
|
||||
}
|
||||
|
||||
usedfont = drw->fonts;
|
||||
while (1) {
|
||||
utf8strlen = 0;
|
||||
utf8str = text;
|
||||
nextfont = NULL;
|
||||
while (*text) {
|
||||
utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
|
||||
for (curfont = drw->fonts; curfont; curfont = curfont->next) {
|
||||
charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
|
||||
if (charexists) {
|
||||
if (curfont == usedfont) {
|
||||
utf8strlen += utf8charlen;
|
||||
text += utf8charlen;
|
||||
} else {
|
||||
nextfont = curfont;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!charexists || nextfont)
|
||||
break;
|
||||
else
|
||||
charexists = 0;
|
||||
}
|
||||
|
||||
if (utf8strlen) {
|
||||
drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL);
|
||||
/* shorten text if necessary */
|
||||
for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--)
|
||||
drw_font_getexts(usedfont, utf8str, len, &ew, NULL);
|
||||
|
||||
if (len) {
|
||||
memcpy(buf, utf8str, len);
|
||||
buf[len] = '\0';
|
||||
if (len < utf8strlen)
|
||||
for (i = len; i && i > len - 3; buf[--i] = '.')
|
||||
; /* NOP */
|
||||
|
||||
if (render) {
|
||||
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
|
||||
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
|
||||
usedfont->xfont, x, ty, (XftChar8 *)buf, len);
|
||||
}
|
||||
x += ew;
|
||||
w -= ew;
|
||||
}
|
||||
}
|
||||
|
||||
if (!*text) {
|
||||
break;
|
||||
} else if (nextfont) {
|
||||
charexists = 0;
|
||||
usedfont = nextfont;
|
||||
} else {
|
||||
/* Regardless of whether or not a fallback font is found, the
|
||||
* character must be drawn. */
|
||||
charexists = 1;
|
||||
|
||||
fccharset = FcCharSetCreate();
|
||||
FcCharSetAddChar(fccharset, utf8codepoint);
|
||||
|
||||
if (!drw->fonts->pattern) {
|
||||
/* Refer to the comment in xfont_create for more information. */
|
||||
die("the first font in the cache must be loaded from a font string.");
|
||||
}
|
||||
|
||||
fcpattern = FcPatternDuplicate(drw->fonts->pattern);
|
||||
FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
|
||||
FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
|
||||
FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
|
||||
|
||||
FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
|
||||
FcDefaultSubstitute(fcpattern);
|
||||
match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
|
||||
|
||||
FcCharSetDestroy(fccharset);
|
||||
FcPatternDestroy(fcpattern);
|
||||
|
||||
if (match) {
|
||||
usedfont = xfont_create(drw, NULL, match);
|
||||
if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
|
||||
for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
|
||||
; /* NOP */
|
||||
curfont->next = usedfont;
|
||||
} else {
|
||||
xfont_free(usedfont);
|
||||
usedfont = drw->fonts;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (d)
|
||||
XftDrawDestroy(d);
|
||||
|
||||
return x + (render ? w : 0);
|
||||
}
|
||||
|
||||
void
|
||||
drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
|
||||
{
|
||||
if (!drw)
|
||||
return;
|
||||
|
||||
XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
|
||||
XSync(drw->dpy, False);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
drw_fontset_getwidth(Drw *drw, const char *text)
|
||||
{
|
||||
if (!drw || !drw->fonts || !text)
|
||||
return 0;
|
||||
return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
|
||||
}
|
||||
|
||||
void
|
||||
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
|
||||
{
|
||||
XGlyphInfo ext;
|
||||
|
||||
if (!font || !text)
|
||||
return;
|
||||
|
||||
XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
|
||||
if (w)
|
||||
*w = ext.xOff;
|
||||
if (h)
|
||||
*h = font->h;
|
||||
}
|
||||
|
||||
Cur *
|
||||
drw_cur_create(Drw *drw, int shape)
|
||||
{
|
||||
Cur *cur;
|
||||
|
||||
if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
|
||||
return NULL;
|
||||
|
||||
cur->cursor = XCreateFontCursor(drw->dpy, shape);
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
void
|
||||
drw_cur_free(Drw *drw, Cur *cursor)
|
||||
{
|
||||
if (!cursor)
|
||||
return;
|
||||
|
||||
XFreeCursor(drw->dpy, cursor->cursor);
|
||||
free(cursor);
|
||||
}
|
57
roles/xmonad/files/dmenu/drw.h
Normal file
57
roles/xmonad/files/dmenu/drw.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
typedef struct {
|
||||
Cursor cursor;
|
||||
} Cur;
|
||||
|
||||
typedef struct Fnt {
|
||||
Display *dpy;
|
||||
unsigned int h;
|
||||
XftFont *xfont;
|
||||
FcPattern *pattern;
|
||||
struct Fnt *next;
|
||||
} Fnt;
|
||||
|
||||
enum { ColFg, ColBg }; /* Clr scheme index */
|
||||
typedef XftColor Clr;
|
||||
|
||||
typedef struct {
|
||||
unsigned int w, h;
|
||||
Display *dpy;
|
||||
int screen;
|
||||
Window root;
|
||||
Drawable drawable;
|
||||
GC gc;
|
||||
Clr *scheme;
|
||||
Fnt *fonts;
|
||||
} Drw;
|
||||
|
||||
/* Drawable abstraction */
|
||||
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
|
||||
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
|
||||
void drw_free(Drw *drw);
|
||||
|
||||
/* Fnt abstraction */
|
||||
Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
|
||||
void drw_fontset_free(Fnt* set);
|
||||
unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
|
||||
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
|
||||
|
||||
/* Colorscheme abstraction */
|
||||
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
|
||||
Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
|
||||
|
||||
/* Cursor abstraction */
|
||||
Cur *drw_cur_create(Drw *drw, int shape);
|
||||
void drw_cur_free(Drw *drw, Cur *cursor);
|
||||
|
||||
/* Drawing context manipulation */
|
||||
void drw_setfontset(Drw *drw, Fnt *set);
|
||||
void drw_setscheme(Drw *drw, Clr *scm);
|
||||
|
||||
/* Drawing functions */
|
||||
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
|
||||
int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
|
||||
|
||||
/* Map functions */
|
||||
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
|
@ -0,0 +1,50 @@
|
||||
From d0c3fc8a634c153856cd41438f705175a21ec69a Mon Sep 17 00:00:00 2001
|
||||
From: braskin <benjaminiraskin@gmail.com>
|
||||
Date: Thu, 12 Nov 2020 10:13:29 -0500
|
||||
Subject: [PATCH] fixed border width draw for topbar
|
||||
|
||||
---
|
||||
config.def.h | 3 +++
|
||||
dmenu.c | 6 +++++-
|
||||
2 files changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
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 65f25ce..716e655 100644
|
||||
--- a/dmenu.c
|
||||
+++ b/dmenu.c
|
||||
@@ -659,9 +659,11 @@ setup(void)
|
||||
swa.override_redirect = True;
|
||||
swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
|
||||
swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
|
||||
- win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
|
||||
+ win = XCreateWindow(dpy, parentwin, x, y - (topbar ? 0 : border_width * 2), mw - border_width * 2, mh, border_width,
|
||||
CopyFromParent, CopyFromParent, CopyFromParent,
|
||||
CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
|
||||
+ if (border_width)
|
||||
+ XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel);
|
||||
XSetClassHint(dpy, win, &ch);
|
||||
|
||||
|
||||
@@ -733,6 +735,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();
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
@ -0,0 +1,120 @@
|
||||
From 8cd37e1ab9e7cb025224aeb3543f1a5be8bceb93 Mon Sep 17 00:00:00 2001
|
||||
From: Nihal Jere <nihal@nihaljere.xyz>
|
||||
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 appears at bottom */
|
||||
+static int centered = 0; /* -c option; centers dmenu on screen */
|
||||
+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 in their $SHELL.
|
||||
.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[i].width);
|
||||
+ 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.width);
|
||||
+ 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 reading stdin */
|
||||
fast = 1;
|
||||
+ else if (!strcmp(argv[i], "-c")) /* centers dmenu on screen */
|
||||
+ centered = 1;
|
||||
else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
|
||||
fstrncmp = strncasecmp;
|
||||
fstrstr = cistrstr;
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,48 @@
|
||||
From 7a045242afac6db70a4aee6e3ac0146cdb264277 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Cole <ajzcole@airmail.cc>
|
||||
Date: Sun, 4 Oct 2020 19:58:32 +1300
|
||||
Subject: [PATCH] listfullwidth patch changes
|
||||
|
||||
---
|
||||
config.def.h | 1 +
|
||||
dmenu.c | 5 +++--
|
||||
2 files changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index 1edb647..221db00 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -2,6 +2,7 @@
|
||||
/* Default settings; can be overriden by command line. */
|
||||
|
||||
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
|
||||
+static int colorprompt = 1; /* -p option; if 1, prompt uses SchemeSel, otherwise SchemeNorm */
|
||||
/* -fn option overrides fonts[0]; default X11 font or font set */
|
||||
static const char *fonts[] = {
|
||||
"monospace:size=10"
|
||||
diff --git a/dmenu.c b/dmenu.c
|
||||
index 65f25ce..f73f299 100644
|
||||
--- a/dmenu.c
|
||||
+++ b/dmenu.c
|
||||
@@ -137,7 +137,8 @@ drawmenu(void)
|
||||
drw_rect(drw, 0, 0, mw, mh, 1, 1);
|
||||
|
||||
if (prompt && *prompt) {
|
||||
- drw_setscheme(drw, scheme[SchemeSel]);
|
||||
+ if (colorprompt)
|
||||
+ drw_setscheme(drw, scheme[SchemeSel]);
|
||||
x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0);
|
||||
}
|
||||
/* draw input field */
|
||||
@@ -154,7 +155,7 @@ drawmenu(void)
|
||||
if (lines > 0) {
|
||||
/* draw vertical list */
|
||||
for (item = curr; item != next; item = item->right)
|
||||
- drawitem(item, x, y += bh, mw - x);
|
||||
+ drawitem(item, 0, y += bh, mw - x);
|
||||
} else if (matches) {
|
||||
/* draw horizontal list */
|
||||
x += inputw;
|
||||
--
|
||||
2.28.0
|
||||
|
90
roles/xmonad/files/dmenu/stest.1
Normal file
90
roles/xmonad/files/dmenu/stest.1
Normal file
@ -0,0 +1,90 @@
|
||||
.TH STEST 1 dmenu\-VERSION
|
||||
.SH NAME
|
||||
stest \- filter a list of files by properties
|
||||
.SH SYNOPSIS
|
||||
.B stest
|
||||
.RB [ -abcdefghlpqrsuwx ]
|
||||
.RB [ -n
|
||||
.IR file ]
|
||||
.RB [ -o
|
||||
.IR file ]
|
||||
.RI [ file ...]
|
||||
.SH DESCRIPTION
|
||||
.B stest
|
||||
takes a list of files and filters by the files' properties, analogous to
|
||||
.IR test (1).
|
||||
Files which pass all tests are printed to stdout. If no files are given, stest
|
||||
reads files from stdin.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-a
|
||||
Test hidden files.
|
||||
.TP
|
||||
.B \-b
|
||||
Test that files are block specials.
|
||||
.TP
|
||||
.B \-c
|
||||
Test that files are character specials.
|
||||
.TP
|
||||
.B \-d
|
||||
Test that files are directories.
|
||||
.TP
|
||||
.B \-e
|
||||
Test that files exist.
|
||||
.TP
|
||||
.B \-f
|
||||
Test that files are regular files.
|
||||
.TP
|
||||
.B \-g
|
||||
Test that files have their set-group-ID flag set.
|
||||
.TP
|
||||
.B \-h
|
||||
Test that files are symbolic links.
|
||||
.TP
|
||||
.B \-l
|
||||
Test the contents of a directory given as an argument.
|
||||
.TP
|
||||
.BI \-n " file"
|
||||
Test that files are newer than
|
||||
.IR file .
|
||||
.TP
|
||||
.BI \-o " file"
|
||||
Test that files are older than
|
||||
.IR file .
|
||||
.TP
|
||||
.B \-p
|
||||
Test that files are named pipes.
|
||||
.TP
|
||||
.B \-q
|
||||
No files are printed, only the exit status is returned.
|
||||
.TP
|
||||
.B \-r
|
||||
Test that files are readable.
|
||||
.TP
|
||||
.B \-s
|
||||
Test that files are not empty.
|
||||
.TP
|
||||
.B \-u
|
||||
Test that files have their set-user-ID flag set.
|
||||
.TP
|
||||
.B \-v
|
||||
Invert the sense of tests, only failing files pass.
|
||||
.TP
|
||||
.B \-w
|
||||
Test that files are writable.
|
||||
.TP
|
||||
.B \-x
|
||||
Test that files are executable.
|
||||
.SH EXIT STATUS
|
||||
.TP
|
||||
.B 0
|
||||
At least one file passed all tests.
|
||||
.TP
|
||||
.B 1
|
||||
No files passed all tests.
|
||||
.TP
|
||||
.B 2
|
||||
An error occurred.
|
||||
.SH SEE ALSO
|
||||
.IR dmenu (1),
|
||||
.IR test (1)
|
109
roles/xmonad/files/dmenu/stest.c
Normal file
109
roles/xmonad/files/dmenu/stest.c
Normal file
@ -0,0 +1,109 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "arg.h"
|
||||
char *argv0;
|
||||
|
||||
#define FLAG(x) (flag[(x)-'a'])
|
||||
|
||||
static void test(const char *, const char *);
|
||||
static void usage(void);
|
||||
|
||||
static int match = 0;
|
||||
static int flag[26];
|
||||
static struct stat old, new;
|
||||
|
||||
static void
|
||||
test(const char *path, const char *name)
|
||||
{
|
||||
struct stat st, ln;
|
||||
|
||||
if ((!stat(path, &st) && (FLAG('a') || name[0] != '.') /* hidden files */
|
||||
&& (!FLAG('b') || S_ISBLK(st.st_mode)) /* block special */
|
||||
&& (!FLAG('c') || S_ISCHR(st.st_mode)) /* character special */
|
||||
&& (!FLAG('d') || S_ISDIR(st.st_mode)) /* directory */
|
||||
&& (!FLAG('e') || access(path, F_OK) == 0) /* exists */
|
||||
&& (!FLAG('f') || S_ISREG(st.st_mode)) /* regular file */
|
||||
&& (!FLAG('g') || st.st_mode & S_ISGID) /* set-group-id flag */
|
||||
&& (!FLAG('h') || (!lstat(path, &ln) && S_ISLNK(ln.st_mode))) /* symbolic link */
|
||||
&& (!FLAG('n') || st.st_mtime > new.st_mtime) /* newer than file */
|
||||
&& (!FLAG('o') || st.st_mtime < old.st_mtime) /* older than file */
|
||||
&& (!FLAG('p') || S_ISFIFO(st.st_mode)) /* named pipe */
|
||||
&& (!FLAG('r') || access(path, R_OK) == 0) /* readable */
|
||||
&& (!FLAG('s') || st.st_size > 0) /* not empty */
|
||||
&& (!FLAG('u') || st.st_mode & S_ISUID) /* set-user-id flag */
|
||||
&& (!FLAG('w') || access(path, W_OK) == 0) /* writable */
|
||||
&& (!FLAG('x') || access(path, X_OK) == 0)) != FLAG('v')) { /* executable */
|
||||
if (FLAG('q'))
|
||||
exit(0);
|
||||
match = 1;
|
||||
puts(name);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [-abcdefghlpqrsuvwx] "
|
||||
"[-n file] [-o file] [file...]\n", argv0);
|
||||
exit(2); /* like test(1) return > 1 on error */
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct dirent *d;
|
||||
char path[PATH_MAX], *line = NULL, *file;
|
||||
size_t linesiz = 0;
|
||||
ssize_t n;
|
||||
DIR *dir;
|
||||
int r;
|
||||
|
||||
ARGBEGIN {
|
||||
case 'n': /* newer than file */
|
||||
case 'o': /* older than file */
|
||||
file = EARGF(usage());
|
||||
if (!(FLAG(ARGC()) = !stat(file, (ARGC() == 'n' ? &new : &old))))
|
||||
perror(file);
|
||||
break;
|
||||
default:
|
||||
/* miscellaneous operators */
|
||||
if (strchr("abcdefghlpqrsuvwx", ARGC()))
|
||||
FLAG(ARGC()) = 1;
|
||||
else
|
||||
usage(); /* unknown flag */
|
||||
} ARGEND;
|
||||
|
||||
if (!argc) {
|
||||
/* read list from stdin */
|
||||
while ((n = getline(&line, &linesiz, stdin)) > 0) {
|
||||
if (n && line[n - 1] == '\n')
|
||||
line[n - 1] = '\0';
|
||||
test(line, line);
|
||||
}
|
||||
free(line);
|
||||
} else {
|
||||
for (; argc; argc--, argv++) {
|
||||
if (FLAG('l') && (dir = opendir(*argv))) {
|
||||
/* test directory contents */
|
||||
while ((d = readdir(dir))) {
|
||||
r = snprintf(path, sizeof path, "%s/%s",
|
||||
*argv, d->d_name);
|
||||
if (r >= 0 && (size_t)r < sizeof path)
|
||||
test(path, d->d_name);
|
||||
}
|
||||
closedir(dir);
|
||||
} else {
|
||||
test(*argv, *argv);
|
||||
}
|
||||
}
|
||||
}
|
||||
return match ? 0 : 1;
|
||||
}
|
35
roles/xmonad/files/dmenu/util.c
Normal file
35
roles/xmonad/files/dmenu/util.c
Normal file
@ -0,0 +1,35 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
void *
|
||||
ecalloc(size_t nmemb, size_t size)
|
||||
{
|
||||
void *p;
|
||||
|
||||
if (!(p = calloc(nmemb, size)))
|
||||
die("calloc:");
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
die(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
|
||||
fputc(' ', stderr);
|
||||
perror(NULL);
|
||||
} else {
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
8
roles/xmonad/files/dmenu/util.h
Normal file
8
roles/xmonad/files/dmenu/util.h
Normal file
@ -0,0 +1,8 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
||||
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
|
||||
|
||||
void die(const char *fmt, ...);
|
||||
void *ecalloc(size_t nmemb, size_t size);
|
60
roles/xmonad/files/profile_t460p
Normal file
60
roles/xmonad/files/profile_t460p
Normal file
@ -0,0 +1,60 @@
|
||||
# first read by bash on login
|
||||
|
||||
# colour scheme for terminal
|
||||
export TERM=xterm-256color
|
||||
|
||||
# colour scheme for gtk applications
|
||||
export GTK_THEME=Adwaita:dark
|
||||
|
||||
# default programs
|
||||
export EDITOR="nvim"
|
||||
export TERMINAL="alacritty"
|
||||
export VISUAL="open_editor_in_new_shell"
|
||||
export READER="zathura"
|
||||
export BROWSER="firefox"
|
||||
|
||||
# environment variables
|
||||
export XDG_CONFIG_HOME="$HOME/.config"
|
||||
export XDG_CACHE_HOME="$HOME/.cache"
|
||||
export XDG_DATA_HOME="$HOME/.local/share"
|
||||
export XDG_RUNTIME_DIR="/run/user/1000"
|
||||
|
||||
export GNUPGHOME="$XDG_DATA_HOME/gnupg"
|
||||
export WINEPREFIX="$XDG_DATA_HOME/wine"
|
||||
export LESSHISTFILE=-
|
||||
#export XAUTHORITY="$XDG_RUNTIME_DIR/Xauthority"
|
||||
export XINITRC="$XDG_CONFIG_HOME/X11/xinitrc"
|
||||
export XSERVERRC="$XDG_CONFIG_HOME/X11/xserverrc"
|
||||
export HISTFILE="$XDG_DATA_HOME/bash/history"
|
||||
export WGETRC="$XDG_CONFIG_HOME/wget/wgetrc"
|
||||
export KDEHOME="$XDG_CONFIG_HOME/kde4"
|
||||
export ANDROID_SDK_ROOT="$XDG_CONFIG_HOME/android"
|
||||
export ADB_VENDOR_KEY="$XDG_CONFIG_HOME/android"
|
||||
export SQLITE_HISTORY="$XDG_DATA_HOME/sqlite_history"
|
||||
export ASPELL_CONF="per-conf $XDG_CONFIG_HOME/aspell/aspell.conf; personal $XDG_CONFIG_HOME/aspell/de.pws; repl $XDG_CONFIG_HOME/aspell/de.prepl"
|
||||
export NPM_CONFIG_USERCONFIG="$XDG_CONFIG_HOME/npm/npmrc"
|
||||
export TS3_CONFIG_DIR="$XDG_CONFIG_HOME/ts3client"
|
||||
export XMONAD_CONFIG_HOME="$XDG_CONFIG_HOME/xmonad"
|
||||
export XMONAD_DATA_HOME="$XDG_DATA_HOME/xmonad"
|
||||
export XMONAD_CACHE_HOME="$XDG_CACHE_HOME/xmonad"
|
||||
export RUSTUP_HOME="$XDG_DATA_HOME/rustup"
|
||||
export CARGO_HOME="$XDG_DATA_HOME/cargo"
|
||||
export PASSWORD_STORE_DIR="$XDG_DATA_HOME/pass"
|
||||
export DVDCSS_CACHE="$XDG_DATA_HOME/dvdcss"
|
||||
export DOTNET_CLI_TELEMETRY_OPTOUT=1
|
||||
export ANSIBLE_HOME="$XDG_CONFIG_HOME/ansible"
|
||||
export ANSIBLE_CONFIG="$XDG_CONFIG_HOME/ansible.cfg"
|
||||
export ANSIBLE_GALAXY_CACHE_DIR="$XDG_CACHE_HOME/ansible/galaxy_cache"
|
||||
export AZURE_CONFIG_DIR="$XDG_DATA_HOME/azure"
|
||||
export NUGET_PACKAGES="$XDG_CACHE_HOME/NuGetPackages"
|
||||
|
||||
# if running bash
|
||||
if [ -n "$BASH_VERSION" ]; then
|
||||
# include .bashrc if it exists
|
||||
if [ -f "$HOME/.bashrc" ]; then
|
||||
. "$HOME/.bashrc"
|
||||
fi
|
||||
fi
|
||||
|
||||
# add private bin and its subdirectories to the $PATH
|
||||
export PATH="$PATH:$XDG_DATA_HOME/cargo/bin:~/.dotnet/tools:$(du "$HOME/.local/bin" | cut -f2 | grep -v git | paste -s -d ':')"
|
24
roles/xmonad/files/slock/LICENSE
Normal file
24
roles/xmonad/files/slock/LICENSE
Normal file
@ -0,0 +1,24 @@
|
||||
MIT/X Consortium License
|
||||
|
||||
© 2015-2016 Markus Teich <markus.teich@stusta.mhn.de>
|
||||
© 2014 Dimitris Papastamos <sin@2f30.org>
|
||||
© 2006-2014 Anselm R Garbe <anselm@garbe.us>
|
||||
© 2014-2016 Laslo Hunhold <dev@frign.de>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
61
roles/xmonad/files/slock/Makefile
Normal file
61
roles/xmonad/files/slock/Makefile
Normal file
@ -0,0 +1,61 @@
|
||||
# slock - simple screen locker
|
||||
# See LICENSE file for copyright and license details.
|
||||
|
||||
include config.mk
|
||||
|
||||
SRC = slock.c ${COMPATSRC}
|
||||
OBJ = ${SRC:.c=.o}
|
||||
|
||||
all: options slock
|
||||
|
||||
options:
|
||||
@echo slock build options:
|
||||
@echo "CFLAGS = ${CFLAGS}"
|
||||
@echo "LDFLAGS = ${LDFLAGS}"
|
||||
@echo "CC = ${CC}"
|
||||
|
||||
.c.o:
|
||||
@echo CC $<
|
||||
@${CC} -c ${CFLAGS} $<
|
||||
|
||||
${OBJ}: config.h config.mk arg.h util.h
|
||||
|
||||
config.h:
|
||||
@echo creating $@ from config.def.h
|
||||
@cp config.def.h $@
|
||||
|
||||
slock: ${OBJ}
|
||||
@echo CC -o $@
|
||||
@${CC} -o $@ ${OBJ} ${LDFLAGS}
|
||||
|
||||
clean:
|
||||
@echo cleaning
|
||||
@rm -f slock ${OBJ} slock-${VERSION}.tar.gz
|
||||
|
||||
dist: clean
|
||||
@echo creating dist tarball
|
||||
@mkdir -p slock-${VERSION}
|
||||
@cp -R LICENSE Makefile README slock.1 config.mk \
|
||||
${SRC} explicit_bzero.c config.def.h arg.h util.h slock-${VERSION}
|
||||
@tar -cf slock-${VERSION}.tar slock-${VERSION}
|
||||
@gzip slock-${VERSION}.tar
|
||||
@rm -rf slock-${VERSION}
|
||||
|
||||
install: all
|
||||
@echo installing executable file to ${DESTDIR}${PREFIX}/bin
|
||||
@mkdir -p ${DESTDIR}${PREFIX}/bin
|
||||
@cp -f slock ${DESTDIR}${PREFIX}/bin
|
||||
@chmod 755 ${DESTDIR}${PREFIX}/bin/slock
|
||||
@chmod u+s ${DESTDIR}${PREFIX}/bin/slock
|
||||
@echo installing manual page to ${DESTDIR}${MANPREFIX}/man1
|
||||
@mkdir -p ${DESTDIR}${MANPREFIX}/man1
|
||||
@sed "s/VERSION/${VERSION}/g" <slock.1 >${DESTDIR}${MANPREFIX}/man1/slock.1
|
||||
@chmod 644 ${DESTDIR}${MANPREFIX}/man1/slock.1
|
||||
|
||||
uninstall:
|
||||
@echo removing executable file from ${DESTDIR}${PREFIX}/bin
|
||||
@rm -f ${DESTDIR}${PREFIX}/bin/slock
|
||||
@echo removing manual page from ${DESTDIR}${MANPREFIX}/man1
|
||||
@rm -f ${DESTDIR}${MANPREFIX}/man1/slock.1
|
||||
|
||||
.PHONY: all options clean dist install uninstall
|
24
roles/xmonad/files/slock/README
Normal file
24
roles/xmonad/files/slock/README
Normal file
@ -0,0 +1,24 @@
|
||||
slock - simple screen locker
|
||||
============================
|
||||
simple screen locker utility for X.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
In order to build slock you need the Xlib header files.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
Edit config.mk to match your local setup (slock is installed into
|
||||
the /usr/local namespace by default).
|
||||
|
||||
Afterwards enter the following command to build and install slock
|
||||
(if necessary as root):
|
||||
|
||||
make clean install
|
||||
|
||||
|
||||
Running slock
|
||||
-------------
|
||||
Simply invoke the 'slock' command. To get out of it, enter your password.
|
65
roles/xmonad/files/slock/arg.h
Normal file
65
roles/xmonad/files/slock/arg.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copy me if you can.
|
||||
* by 20h
|
||||
*/
|
||||
|
||||
#ifndef ARG_H__
|
||||
#define ARG_H__
|
||||
|
||||
extern char *argv0;
|
||||
|
||||
/* use main(int argc, char *argv[]) */
|
||||
#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\
|
||||
argv[0] && argv[0][0] == '-'\
|
||||
&& argv[0][1];\
|
||||
argc--, argv++) {\
|
||||
char argc_;\
|
||||
char **argv_;\
|
||||
int brk_;\
|
||||
if (argv[0][1] == '-' && argv[0][2] == '\0') {\
|
||||
argv++;\
|
||||
argc--;\
|
||||
break;\
|
||||
}\
|
||||
for (brk_ = 0, argv[0]++, argv_ = argv;\
|
||||
argv[0][0] && !brk_;\
|
||||
argv[0]++) {\
|
||||
if (argv_ != argv)\
|
||||
break;\
|
||||
argc_ = argv[0][0];\
|
||||
switch (argc_)
|
||||
|
||||
/* Handles obsolete -NUM syntax */
|
||||
#define ARGNUM case '0':\
|
||||
case '1':\
|
||||
case '2':\
|
||||
case '3':\
|
||||
case '4':\
|
||||
case '5':\
|
||||
case '6':\
|
||||
case '7':\
|
||||
case '8':\
|
||||
case '9'
|
||||
|
||||
#define ARGEND }\
|
||||
}
|
||||
|
||||
#define ARGC() argc_
|
||||
|
||||
#define ARGNUMF() (brk_ = 1, estrtonum(argv[0], 0, INT_MAX))
|
||||
|
||||
#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\
|
||||
((x), abort(), (char *)0) :\
|
||||
(brk_ = 1, (argv[0][1] != '\0')?\
|
||||
(&argv[0][1]) :\
|
||||
(argc--, argv++, argv[0])))
|
||||
|
||||
#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\
|
||||
(char *)0 :\
|
||||
(brk_ = 1, (argv[0][1] != '\0')?\
|
||||
(&argv[0][1]) :\
|
||||
(argc--, argv++, argv[0])))
|
||||
|
||||
#define LNGARG() &argv[0][0]
|
||||
|
||||
#endif
|
21
roles/xmonad/files/slock/config.def.h
Normal file
21
roles/xmonad/files/slock/config.def.h
Normal file
@ -0,0 +1,21 @@
|
||||
/* user and group to drop privileges to */
|
||||
static const char *user = "nobody";
|
||||
static const char *group = "nogroup";
|
||||
|
||||
static const char *colorname[NUMCOLS] = {
|
||||
[INIT] = "black", /* after initialization */
|
||||
[INPUT] = "#005577", /* during input */
|
||||
[FAILED] = "#CC3333", /* wrong password */
|
||||
};
|
||||
|
||||
/* treat a cleared input like a wrong password (color) */
|
||||
static const int failonclear = 1;
|
||||
|
||||
/*Enable blur*/
|
||||
#define BLUR
|
||||
/*Set blur radius*/
|
||||
static const int blurRadius=5;
|
||||
/*Enable Pixelation*/
|
||||
//#define PIXELATION
|
||||
/*Set pixelation radius*/
|
||||
static const int pixelSize=0;
|
21
roles/xmonad/files/slock/config.h
Normal file
21
roles/xmonad/files/slock/config.h
Normal file
@ -0,0 +1,21 @@
|
||||
/* user and group to drop privileges to */
|
||||
static const char *user = "max";
|
||||
static const char *group = "max";
|
||||
|
||||
static const char *colorname[NUMCOLS] = {
|
||||
[INIT] = "black", /* after initialization */
|
||||
[INPUT] = "#005577", /* during input */
|
||||
[FAILED] = "#CC3333", /* wrong password */
|
||||
};
|
||||
|
||||
/* treat a cleared input like a wrong password (color) */
|
||||
static const int failonclear = 1;
|
||||
|
||||
/*Enable blur*/
|
||||
#define BLUR
|
||||
/*Set blur radius*/
|
||||
static const int blurRadius=7;
|
||||
/*Enable Pixelation*/
|
||||
/* #define PIXELATION */
|
||||
/*Set pixelation radius*/
|
||||
static const int pixelSize=0;
|
32
roles/xmonad/files/slock/config.mk
Normal file
32
roles/xmonad/files/slock/config.mk
Normal file
@ -0,0 +1,32 @@
|
||||
# slock version
|
||||
VERSION = 1.4
|
||||
|
||||
# Customize below to fit your system
|
||||
|
||||
# paths
|
||||
PREFIX = /usr/local
|
||||
MANPREFIX = ${PREFIX}/share/man
|
||||
|
||||
X11INC = /usr/X11R6/include
|
||||
X11LIB = /usr/X11R6/lib
|
||||
|
||||
# includes and libs
|
||||
INCS = -I. -I/usr/include -I${X11INC}
|
||||
LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr -lImlib2
|
||||
|
||||
# flags
|
||||
CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H
|
||||
CFLAGS = -std=c99 -pedantic -Wall -Ofast ${INCS} ${CPPFLAGS}
|
||||
LDFLAGS = -s ${LIBS}
|
||||
COMPATSRC = explicit_bzero.c
|
||||
|
||||
# On OpenBSD and Darwin remove -lcrypt from LIBS
|
||||
#LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lXext -lXrandr
|
||||
# On *BSD remove -DHAVE_SHADOW_H from CPPFLAGS
|
||||
# On NetBSD add -D_NETBSD_SOURCE to CPPFLAGS
|
||||
#CPPFLAGS = -DVERSION=\"${VERSION}\" -D_BSD_SOURCE -D_NETBSD_SOURCE
|
||||
# On OpenBSD set COMPATSRC to empty
|
||||
#COMPATSRC =
|
||||
|
||||
# compiler and linker
|
||||
CC = cc
|
19
roles/xmonad/files/slock/explicit_bzero.c
Normal file
19
roles/xmonad/files/slock/explicit_bzero.c
Normal file
@ -0,0 +1,19 @@
|
||||
/* $OpenBSD: explicit_bzero.c,v 1.3 2014/06/21 02:34:26 matthew Exp $ */
|
||||
/*
|
||||
* Public domain.
|
||||
* Written by Matthew Dempsky.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
__attribute__((weak)) void
|
||||
__explicit_bzero_hook(void *buf, size_t len)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
explicit_bzero(void *buf, size_t len)
|
||||
{
|
||||
memset(buf, 0, len);
|
||||
__explicit_bzero_hook(buf, len);
|
||||
}
|
@ -0,0 +1,356 @@
|
||||
From 36a4863f9a399740aaf8b1e01926485c0a055e1c Mon Sep 17 00:00:00 2001
|
||||
From: Lars Niesen <iah71niesen@gso-koeln.de>
|
||||
Date: Wed, 29 Apr 2020 13:52:42 +0200
|
||||
Subject: [PATCH 1/8] Added Bg patch and screenshot capabilities
|
||||
|
||||
---
|
||||
config.mk | 2 +-
|
||||
slock.c | 35 +++++++++++++++++++++++++++++++----
|
||||
2 files changed, 32 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/config.mk b/config.mk
|
||||
index 74429ae..987819e 100644
|
||||
--- a/config.mk
|
||||
+++ b/config.mk
|
||||
@@ -12,7 +12,7 @@ X11LIB = /usr/X11R6/lib
|
||||
|
||||
# includes and libs
|
||||
INCS = -I. -I/usr/include -I${X11INC}
|
||||
-LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr
|
||||
+LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr -lImlib2
|
||||
|
||||
# flags
|
||||
CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H
|
||||
diff --git a/slock.c b/slock.c
|
||||
index 5ae738c..7c63f34 100644
|
||||
--- a/slock.c
|
||||
+++ b/slock.c
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
+#include <Imlib2.h>
|
||||
|
||||
#include "arg.h"
|
||||
#include "util.h"
|
||||
@@ -35,6 +36,7 @@ struct lock {
|
||||
int screen;
|
||||
Window root, win;
|
||||
Pixmap pmap;
|
||||
+ Pixmap bgmap;
|
||||
unsigned long colors[NUMCOLS];
|
||||
};
|
||||
|
||||
@@ -46,6 +48,8 @@ struct xrandr {
|
||||
|
||||
#include "config.h"
|
||||
|
||||
+Imlib_Image image;
|
||||
+
|
||||
static void
|
||||
die(const char *errstr, ...)
|
||||
{
|
||||
@@ -190,9 +194,10 @@ readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
|
||||
color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT);
|
||||
if (running && oldc != color) {
|
||||
for (screen = 0; screen < nscreens; screen++) {
|
||||
- XSetWindowBackground(dpy,
|
||||
- locks[screen]->win,
|
||||
- locks[screen]->colors[color]);
|
||||
+ if(locks[screen]->bgmap)
|
||||
+ XSetWindowBackgroundPixmap(dpy, locks[screen]->win, locks[screen]->bgmap);
|
||||
+ else
|
||||
+ XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[0]);
|
||||
XClearWindow(dpy, locks[screen]->win);
|
||||
}
|
||||
oldc = color;
|
||||
@@ -235,6 +240,17 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
|
||||
lock->screen = screen;
|
||||
lock->root = RootWindow(dpy, lock->screen);
|
||||
|
||||
+ if(image)
|
||||
+ {
|
||||
+ lock->bgmap = XCreatePixmap(dpy, lock->root, DisplayWidth(dpy, lock->screen), DisplayHeight(dpy, lock->screen), DefaultDepth(dpy, lock->screen));
|
||||
+ imlib_context_set_image(image);
|
||||
+ imlib_context_set_display(dpy);
|
||||
+ imlib_context_set_visual(DefaultVisual(dpy, lock->screen));
|
||||
+ imlib_context_set_colormap(DefaultColormap(dpy, lock->screen));
|
||||
+ imlib_context_set_drawable(lock->bgmap);
|
||||
+ imlib_render_image_on_drawable(0, 0);
|
||||
+ imlib_free_image();
|
||||
+ }
|
||||
for (i = 0; i < NUMCOLS; i++) {
|
||||
XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen),
|
||||
colorname[i], &color, &dummy);
|
||||
@@ -251,6 +267,8 @@ lockscreen(Display *dpy, struct xrandr *rr, int screen)
|
||||
CopyFromParent,
|
||||
DefaultVisual(dpy, lock->screen),
|
||||
CWOverrideRedirect | CWBackPixel, &wa);
|
||||
+ if(lock->bgmap)
|
||||
+ XSetWindowBackgroundPixmap(dpy, lock->win, lock->bgmap);
|
||||
lock->pmap = XCreateBitmapFromData(dpy, lock->win, curs, 8, 8);
|
||||
invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap,
|
||||
&color, &color, 0, 0);
|
||||
@@ -354,7 +372,16 @@ main(int argc, char **argv) {
|
||||
die("slock: setgid: %s\n", strerror(errno));
|
||||
if (setuid(duid) < 0)
|
||||
die("slock: setuid: %s\n", strerror(errno));
|
||||
-
|
||||
+
|
||||
+ /*Create screenshot Image*/
|
||||
+ Screen *scr = ScreenOfDisplay(dpy, DefaultScreen(dpy));
|
||||
+ image = imlib_create_image(scr->width,scr->height);
|
||||
+ imlib_context_set_image(image);
|
||||
+ imlib_context_set_display(dpy);
|
||||
+ imlib_context_set_visual(DefaultVisual(dpy,0));
|
||||
+ imlib_context_set_drawable(RootWindow(dpy,XScreenNumberOfScreen(scr)));
|
||||
+ imlib_copy_drawable_to_image(0,0,0,scr->width,scr->height,0,0,1);
|
||||
+
|
||||
/* check for Xrandr support */
|
||||
rr.active = XRRQueryExtension(dpy, &rr.evbase, &rr.errbase);
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
|
||||
From 9d89604ac52b0949d047dae2f9b78cb5085ee1a2 Mon Sep 17 00:00:00 2001
|
||||
From: Lars Niesen <iah71niesen@gso-koeln.de>
|
||||
Date: Wed, 29 Apr 2020 14:15:59 +0200
|
||||
Subject: [PATCH 2/8] Added blur function
|
||||
|
||||
---
|
||||
config.def.h | 3 +++
|
||||
slock.c | 3 ++-
|
||||
2 files changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index c8e52d6..fcc1b39 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -10,3 +10,6 @@ static const char *colorname[NUMCOLS] = {
|
||||
|
||||
/* treat a cleared input like a wrong password (color) */
|
||||
static const int failonclear = 1;
|
||||
+
|
||||
+/*Set Blur radius*/
|
||||
+static const int blurRadius=5;
|
||||
\ No newline at end of file
|
||||
diff --git a/slock.c b/slock.c
|
||||
index 7c63f34..0f24cd7 100644
|
||||
--- a/slock.c
|
||||
+++ b/slock.c
|
||||
@@ -372,7 +372,7 @@ main(int argc, char **argv) {
|
||||
die("slock: setgid: %s\n", strerror(errno));
|
||||
if (setuid(duid) < 0)
|
||||
die("slock: setuid: %s\n", strerror(errno));
|
||||
-
|
||||
+
|
||||
/*Create screenshot Image*/
|
||||
Screen *scr = ScreenOfDisplay(dpy, DefaultScreen(dpy));
|
||||
image = imlib_create_image(scr->width,scr->height);
|
||||
@@ -381,6 +381,7 @@ main(int argc, char **argv) {
|
||||
imlib_context_set_visual(DefaultVisual(dpy,0));
|
||||
imlib_context_set_drawable(RootWindow(dpy,XScreenNumberOfScreen(scr)));
|
||||
imlib_copy_drawable_to_image(0,0,0,scr->width,scr->height,0,0,1);
|
||||
+ imlib_image_blur(blurRadius);
|
||||
|
||||
/* check for Xrandr support */
|
||||
rr.active = XRRQueryExtension(dpy, &rr.evbase, &rr.errbase);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
|
||||
From 069aabd7e30244befd4efe74c85d3468ed076c21 Mon Sep 17 00:00:00 2001
|
||||
From: Lars Niesen <iah71niesen@gso-koeln.de>
|
||||
Date: Wed, 29 Apr 2020 17:33:09 +0200
|
||||
Subject: [PATCH 4/8] added Pixelation
|
||||
|
||||
---
|
||||
config.def.h | 3 ++-
|
||||
slock.c | 42 ++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 44 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index fcc1b39..1c1aef3 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -12,4 +12,5 @@ static const char *colorname[NUMCOLS] = {
|
||||
static const int failonclear = 1;
|
||||
|
||||
/*Set Blur radius*/
|
||||
-static const int blurRadius=5;
|
||||
\ No newline at end of file
|
||||
+static const int blurRadius=0;
|
||||
+static const int pixelSize=5;
|
||||
diff --git a/slock.c b/slock.c
|
||||
index 0f24cd7..33ca569 100644
|
||||
--- a/slock.c
|
||||
+++ b/slock.c
|
||||
@@ -381,7 +381,49 @@ main(int argc, char **argv) {
|
||||
imlib_context_set_visual(DefaultVisual(dpy,0));
|
||||
imlib_context_set_drawable(RootWindow(dpy,XScreenNumberOfScreen(scr)));
|
||||
imlib_copy_drawable_to_image(0,0,0,scr->width,scr->height,0,0,1);
|
||||
+
|
||||
+ /*Blur function*/
|
||||
imlib_image_blur(blurRadius);
|
||||
+
|
||||
+
|
||||
+ /*Pixelation*/
|
||||
+ int width = scr->width;
|
||||
+ int height = scr->height;
|
||||
+
|
||||
+ for(int y = 0; y < height; y += pixelSize)
|
||||
+ {
|
||||
+ for(int x = 0; x < width; x += pixelSize)
|
||||
+ {
|
||||
+ int red = 0;
|
||||
+ int green = 0;
|
||||
+ int blue = 0;
|
||||
+
|
||||
+ Imlib_Color pixel;
|
||||
+ Imlib_Color* pp;
|
||||
+ pp = &pixel;
|
||||
+ for(int j = 0; j < pixelSize && j < height; j++)
|
||||
+ {
|
||||
+ for(int i = 0; i < pixelSize && i < width; i++)
|
||||
+ {
|
||||
+ imlib_image_query_pixel(x+i,y+j,pp);
|
||||
+ red += pixel.red;
|
||||
+ green += pixel.green;
|
||||
+ blue += pixel.blue;
|
||||
+ }
|
||||
+ }
|
||||
+ red /= (pixelSize*pixelSize);
|
||||
+ green /= (pixelSize*pixelSize);
|
||||
+ blue /= (pixelSize*pixelSize);
|
||||
+ printf("R/G/B: %i/%i/%i\n",red,green,blue);
|
||||
+ imlib_context_set_color(red,green,blue,pixel.alpha);
|
||||
+ imlib_image_fill_rectangle(x,y,pixelSize,pixelSize);
|
||||
+ red = 0;
|
||||
+ green = 0;
|
||||
+ blue = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+
|
||||
|
||||
/* check for Xrandr support */
|
||||
rr.active = XRRQueryExtension(dpy, &rr.evbase, &rr.errbase);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
|
||||
From 109bac015c1c7fbf8440fb42588fe7e0e9cb5e62 Mon Sep 17 00:00:00 2001
|
||||
From: Lars Niesen <iah71niesen@gso-koeln.de>
|
||||
Date: Wed, 29 Apr 2020 17:42:39 +0200
|
||||
Subject: [PATCH 6/8] removed debug printf
|
||||
|
||||
---
|
||||
slock.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/slock.c b/slock.c
|
||||
index 33ca569..f54c459 100644
|
||||
--- a/slock.c
|
||||
+++ b/slock.c
|
||||
@@ -414,7 +414,6 @@ main(int argc, char **argv) {
|
||||
red /= (pixelSize*pixelSize);
|
||||
green /= (pixelSize*pixelSize);
|
||||
blue /= (pixelSize*pixelSize);
|
||||
- printf("R/G/B: %i/%i/%i\n",red,green,blue);
|
||||
imlib_context_set_color(red,green,blue,pixel.alpha);
|
||||
imlib_image_fill_rectangle(x,y,pixelSize,pixelSize);
|
||||
red = 0;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
|
||||
From a13a0f4ac86f82e4dff145b7ebd93e52d07492c9 Mon Sep 17 00:00:00 2001
|
||||
From: Lars Niesen <iah71niesen@gso-koeln.de>
|
||||
Date: Sun, 3 May 2020 18:03:38 +0200
|
||||
Subject: [PATCH 7/8] Changed compilerflag to fast
|
||||
|
||||
---
|
||||
config.mk | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/config.mk b/config.mk
|
||||
index 987819e..d0c2f01 100644
|
||||
--- a/config.mk
|
||||
+++ b/config.mk
|
||||
@@ -16,7 +16,7 @@ LIBS = -L/usr/lib -lc -lcrypt -L${X11LIB} -lX11 -lXext -lXrandr -lImlib2
|
||||
|
||||
# flags
|
||||
CPPFLAGS = -DVERSION=\"${VERSION}\" -D_DEFAULT_SOURCE -DHAVE_SHADOW_H
|
||||
-CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
|
||||
+CFLAGS = -std=c99 -pedantic -Wall -Ofast ${INCS} ${CPPFLAGS}
|
||||
LDFLAGS = -s ${LIBS}
|
||||
COMPATSRC = explicit_bzero.c
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
|
||||
From 31a7001c4954606c066cc3df4318fafd6d216bcd Mon Sep 17 00:00:00 2001
|
||||
From: Lars Niesen <iah71niesen@gso-koeln.de>
|
||||
Date: Mon, 4 May 2020 10:00:40 +0200
|
||||
Subject: [PATCH 8/8] Added defines for BLUR/PIXELATION to remove from code by
|
||||
compilation
|
||||
|
||||
---
|
||||
config.def.h | 11 ++++++++---
|
||||
slock.c | 9 ++++++---
|
||||
2 files changed, 14 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index 1c1aef3..5407953 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -11,6 +11,11 @@ static const char *colorname[NUMCOLS] = {
|
||||
/* treat a cleared input like a wrong password (color) */
|
||||
static const int failonclear = 1;
|
||||
|
||||
-/*Set Blur radius*/
|
||||
-static const int blurRadius=0;
|
||||
-static const int pixelSize=5;
|
||||
+/*Enable blur*/
|
||||
+#define BLUR
|
||||
+/*Set blur radius*/
|
||||
+static const int blurRadius=5;
|
||||
+/*Enable Pixelation*/
|
||||
+//#define PIXELATION
|
||||
+/*Set pixelation radius*/
|
||||
+static const int pixelSize=0;
|
||||
diff --git a/slock.c b/slock.c
|
||||
index f54c459..1a4d6e3 100644
|
||||
--- a/slock.c
|
||||
+++ b/slock.c
|
||||
@@ -381,11 +381,14 @@ main(int argc, char **argv) {
|
||||
imlib_context_set_visual(DefaultVisual(dpy,0));
|
||||
imlib_context_set_drawable(RootWindow(dpy,XScreenNumberOfScreen(scr)));
|
||||
imlib_copy_drawable_to_image(0,0,0,scr->width,scr->height,0,0,1);
|
||||
-
|
||||
+
|
||||
+#ifdef BLUR
|
||||
+
|
||||
/*Blur function*/
|
||||
imlib_image_blur(blurRadius);
|
||||
+#endif // BLUR
|
||||
|
||||
-
|
||||
+#ifdef PIXELATION
|
||||
/*Pixelation*/
|
||||
int width = scr->width;
|
||||
int height = scr->height;
|
||||
@@ -423,7 +426,7 @@ main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
|
||||
-
|
||||
+#endif
|
||||
/* check for Xrandr support */
|
||||
rr.active = XRRQueryExtension(dpy, &rr.evbase, &rr.errbase);
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
39
roles/xmonad/files/slock/slock.1
Normal file
39
roles/xmonad/files/slock/slock.1
Normal file
@ -0,0 +1,39 @@
|
||||
.Dd 2016-08-23
|
||||
.Dt SLOCK 1
|
||||
.Sh NAME
|
||||
.Nm slock
|
||||
.Nd simple X screen locker
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl v
|
||||
.Op Ar cmd Op Ar arg ...
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is a simple X screen locker. If provided,
|
||||
.Ar cmd Op Ar arg ...
|
||||
is executed after the screen has been locked.
|
||||
.Sh OPTIONS
|
||||
.Bl -tag -width Ds
|
||||
.It Fl v
|
||||
Print version information to stdout and exit.
|
||||
.El
|
||||
.Sh SECURITY CONSIDERATIONS
|
||||
To make sure a locked screen can not be bypassed by switching VTs
|
||||
or killing the X server with Ctrl+Alt+Backspace, it is recommended
|
||||
to disable both in
|
||||
.Xr xorg.conf 5
|
||||
for maximum security:
|
||||
.Bd -literal -offset left
|
||||
Section "ServerFlags"
|
||||
Option "DontVTSwitch" "True"
|
||||
Option "DontZap" "True"
|
||||
EndSection
|
||||
.Ed
|
||||
.Sh EXAMPLES
|
||||
$
|
||||
.Nm
|
||||
/usr/sbin/s2ram
|
||||
.Sh CUSTOMIZATION
|
||||
.Nm
|
||||
can be customized by creating a custom config.h from config.def.h and
|
||||
(re)compiling the source code. This keeps it fast, secure and simple.
|
459
roles/xmonad/files/slock/slock.c
Normal file
459
roles/xmonad/files/slock/slock.c
Normal file
@ -0,0 +1,459 @@
|
||||
/* See LICENSE file for license details. */
|
||||
#define _XOPEN_SOURCE 500
|
||||
#if HAVE_SHADOW_H
|
||||
#include <shadow.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <Imlib2.h>
|
||||
|
||||
#include "arg.h"
|
||||
#include "util.h"
|
||||
|
||||
char *argv0;
|
||||
|
||||
enum {
|
||||
INIT,
|
||||
INPUT,
|
||||
FAILED,
|
||||
NUMCOLS
|
||||
};
|
||||
|
||||
struct lock {
|
||||
int screen;
|
||||
Window root, win;
|
||||
Pixmap pmap;
|
||||
Pixmap bgmap;
|
||||
unsigned long colors[NUMCOLS];
|
||||
};
|
||||
|
||||
struct xrandr {
|
||||
int active;
|
||||
int evbase;
|
||||
int errbase;
|
||||
};
|
||||
|
||||
#include "config.h"
|
||||
|
||||
Imlib_Image image;
|
||||
|
||||
static void
|
||||
die(const char *errstr, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, errstr);
|
||||
vfprintf(stderr, errstr, ap);
|
||||
va_end(ap);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
#include <fcntl.h>
|
||||
#include <linux/oom.h>
|
||||
|
||||
static void
|
||||
dontkillme(void)
|
||||
{
|
||||
FILE *f;
|
||||
const char oomfile[] = "/proc/self/oom_score_adj";
|
||||
|
||||
if (!(f = fopen(oomfile, "w"))) {
|
||||
if (errno == ENOENT)
|
||||
return;
|
||||
die("slock: fopen %s: %s\n", oomfile, strerror(errno));
|
||||
}
|
||||
fprintf(f, "%d", OOM_SCORE_ADJ_MIN);
|
||||
if (fclose(f)) {
|
||||
if (errno == EACCES)
|
||||
die("slock: unable to disable OOM killer. "
|
||||
"Make sure to suid or sgid slock.\n");
|
||||
else
|
||||
die("slock: fclose %s: %s\n", oomfile, strerror(errno));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char *
|
||||
gethash(void)
|
||||
{
|
||||
const char *hash;
|
||||
struct passwd *pw;
|
||||
|
||||
/* Check if the current user has a password entry */
|
||||
errno = 0;
|
||||
if (!(pw = getpwuid(getuid()))) {
|
||||
if (errno)
|
||||
die("slock: getpwuid: %s\n", strerror(errno));
|
||||
else
|
||||
die("slock: cannot retrieve password entry\n");
|
||||
}
|
||||
hash = pw->pw_passwd;
|
||||
|
||||
#if HAVE_SHADOW_H
|
||||
if (!strcmp(hash, "x")) {
|
||||
struct spwd *sp;
|
||||
if (!(sp = getspnam(pw->pw_name)))
|
||||
die("slock: getspnam: cannot retrieve shadow entry. "
|
||||
"Make sure to suid or sgid slock.\n");
|
||||
hash = sp->sp_pwdp;
|
||||
}
|
||||
#else
|
||||
if (!strcmp(hash, "*")) {
|
||||
#ifdef __OpenBSD__
|
||||
if (!(pw = getpwuid_shadow(getuid())))
|
||||
die("slock: getpwnam_shadow: cannot retrieve shadow entry. "
|
||||
"Make sure to suid or sgid slock.\n");
|
||||
hash = pw->pw_passwd;
|
||||
#else
|
||||
die("slock: getpwuid: cannot retrieve shadow entry. "
|
||||
"Make sure to suid or sgid slock.\n");
|
||||
#endif /* __OpenBSD__ */
|
||||
}
|
||||
#endif /* HAVE_SHADOW_H */
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static void
|
||||
readpw(Display *dpy, struct xrandr *rr, struct lock **locks, int nscreens,
|
||||
const char *hash)
|
||||
{
|
||||
XRRScreenChangeNotifyEvent *rre;
|
||||
char buf[32], passwd[256], *inputhash;
|
||||
int num, screen, running, failure, oldc;
|
||||
unsigned int len, color;
|
||||
KeySym ksym;
|
||||
XEvent ev;
|
||||
|
||||
len = 0;
|
||||
running = 1;
|
||||
failure = 0;
|
||||
oldc = INIT;
|
||||
|
||||
while (running && !XNextEvent(dpy, &ev)) {
|
||||
if (ev.type == KeyPress) {
|
||||
explicit_bzero(&buf, sizeof(buf));
|
||||
num = XLookupString(&ev.xkey, buf, sizeof(buf), &ksym, 0);
|
||||
if (IsKeypadKey(ksym)) {
|
||||
if (ksym == XK_KP_Enter)
|
||||
ksym = XK_Return;
|
||||
else if (ksym >= XK_KP_0 && ksym <= XK_KP_9)
|
||||
ksym = (ksym - XK_KP_0) + XK_0;
|
||||
}
|
||||
if (IsFunctionKey(ksym) ||
|
||||
IsKeypadKey(ksym) ||
|
||||
IsMiscFunctionKey(ksym) ||
|
||||
IsPFKey(ksym) ||
|
||||
IsPrivateKeypadKey(ksym))
|
||||
continue;
|
||||
switch (ksym) {
|
||||
case XK_Return:
|
||||
passwd[len] = '\0';
|
||||
errno = 0;
|
||||
if (!(inputhash = crypt(passwd, hash)))
|
||||
fprintf(stderr, "slock: crypt: %s\n", strerror(errno));
|
||||
else
|
||||
running = !!strcmp(inputhash, hash);
|
||||
if (running) {
|
||||
XBell(dpy, 100);
|
||||
failure = 1;
|
||||
}
|
||||
explicit_bzero(&passwd, sizeof(passwd));
|
||||
len = 0;
|
||||
break;
|
||||
case XK_Escape:
|
||||
explicit_bzero(&passwd, sizeof(passwd));
|
||||
len = 0;
|
||||
break;
|
||||
case XK_BackSpace:
|
||||
if (len)
|
||||
passwd[len--] = '\0';
|
||||
break;
|
||||
default:
|
||||
if (num && !iscntrl((int)buf[0]) &&
|
||||
(len + num < sizeof(passwd))) {
|
||||
memcpy(passwd + len, buf, num);
|
||||
len += num;
|
||||
}
|
||||
break;
|
||||
}
|
||||
color = len ? INPUT : ((failure || failonclear) ? FAILED : INIT);
|
||||
if (running && oldc != color) {
|
||||
for (screen = 0; screen < nscreens; screen++) {
|
||||
if(locks[screen]->bgmap)
|
||||
XSetWindowBackgroundPixmap(dpy, locks[screen]->win, locks[screen]->bgmap);
|
||||
else
|
||||
XSetWindowBackground(dpy, locks[screen]->win, locks[screen]->colors[0]);
|
||||
XClearWindow(dpy, locks[screen]->win);
|
||||
}
|
||||
oldc = color;
|
||||
}
|
||||
} else if (rr->active && ev.type == rr->evbase + RRScreenChangeNotify) {
|
||||
rre = (XRRScreenChangeNotifyEvent*)&ev;
|
||||
for (screen = 0; screen < nscreens; screen++) {
|
||||
if (locks[screen]->win == rre->window) {
|
||||
XResizeWindow(dpy, locks[screen]->win,
|
||||
rre->width, rre->height);
|
||||
XClearWindow(dpy, locks[screen]->win);
|
||||
}
|
||||
}
|
||||
} else for (screen = 0; screen < nscreens; screen++)
|
||||
XRaiseWindow(dpy, locks[screen]->win);
|
||||
}
|
||||
}
|
||||
|
||||
static struct lock *
|
||||
lockscreen(Display *dpy, struct xrandr *rr, int screen)
|
||||
{
|
||||
char curs[] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int i, ptgrab, kbgrab;
|
||||
struct lock *lock;
|
||||
XColor color, dummy;
|
||||
XSetWindowAttributes wa;
|
||||
Cursor invisible;
|
||||
|
||||
if (dpy == NULL || screen < 0 || !(lock = malloc(sizeof(struct lock))))
|
||||
return NULL;
|
||||
|
||||
lock->screen = screen;
|
||||
lock->root = RootWindow(dpy, lock->screen);
|
||||
|
||||
if(image)
|
||||
{
|
||||
lock->bgmap = XCreatePixmap(dpy, lock->root, DisplayWidth(dpy, lock->screen), DisplayHeight(dpy, lock->screen), DefaultDepth(dpy, lock->screen));
|
||||
imlib_context_set_image(image);
|
||||
imlib_context_set_display(dpy);
|
||||
imlib_context_set_visual(DefaultVisual(dpy, lock->screen));
|
||||
imlib_context_set_colormap(DefaultColormap(dpy, lock->screen));
|
||||
imlib_context_set_drawable(lock->bgmap);
|
||||
imlib_render_image_on_drawable(0, 0);
|
||||
imlib_free_image();
|
||||
}
|
||||
for (i = 0; i < NUMCOLS; i++) {
|
||||
XAllocNamedColor(dpy, DefaultColormap(dpy, lock->screen),
|
||||
colorname[i], &color, &dummy);
|
||||
lock->colors[i] = color.pixel;
|
||||
}
|
||||
|
||||
/* init */
|
||||
wa.override_redirect = 1;
|
||||
wa.background_pixel = lock->colors[INIT];
|
||||
lock->win = XCreateWindow(dpy, lock->root, 0, 0,
|
||||
DisplayWidth(dpy, lock->screen),
|
||||
DisplayHeight(dpy, lock->screen),
|
||||
0, DefaultDepth(dpy, lock->screen),
|
||||
CopyFromParent,
|
||||
DefaultVisual(dpy, lock->screen),
|
||||
CWOverrideRedirect | CWBackPixel, &wa);
|
||||
if(lock->bgmap)
|
||||
XSetWindowBackgroundPixmap(dpy, lock->win, lock->bgmap);
|
||||
lock->pmap = XCreateBitmapFromData(dpy, lock->win, curs, 8, 8);
|
||||
invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap,
|
||||
&color, &color, 0, 0);
|
||||
XDefineCursor(dpy, lock->win, invisible);
|
||||
|
||||
/* Try to grab mouse pointer *and* keyboard for 600ms, else fail the lock */
|
||||
for (i = 0, ptgrab = kbgrab = -1; i < 6; i++) {
|
||||
if (ptgrab != GrabSuccess) {
|
||||
ptgrab = XGrabPointer(dpy, lock->root, False,
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
PointerMotionMask, GrabModeAsync,
|
||||
GrabModeAsync, None, invisible, CurrentTime);
|
||||
}
|
||||
if (kbgrab != GrabSuccess) {
|
||||
kbgrab = XGrabKeyboard(dpy, lock->root, True,
|
||||
GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
}
|
||||
|
||||
/* input is grabbed: we can lock the screen */
|
||||
if (ptgrab == GrabSuccess && kbgrab == GrabSuccess) {
|
||||
XMapRaised(dpy, lock->win);
|
||||
if (rr->active)
|
||||
XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask);
|
||||
|
||||
XSelectInput(dpy, lock->root, SubstructureNotifyMask);
|
||||
return lock;
|
||||
}
|
||||
|
||||
/* retry on AlreadyGrabbed but fail on other errors */
|
||||
if ((ptgrab != AlreadyGrabbed && ptgrab != GrabSuccess) ||
|
||||
(kbgrab != AlreadyGrabbed && kbgrab != GrabSuccess))
|
||||
break;
|
||||
|
||||
usleep(100000);
|
||||
}
|
||||
|
||||
/* we couldn't grab all input: fail out */
|
||||
if (ptgrab != GrabSuccess)
|
||||
fprintf(stderr, "slock: unable to grab mouse pointer for screen %d\n",
|
||||
screen);
|
||||
if (kbgrab != GrabSuccess)
|
||||
fprintf(stderr, "slock: unable to grab keyboard for screen %d\n",
|
||||
screen);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
die("usage: slock [-v] [cmd [arg ...]]\n");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv) {
|
||||
struct xrandr rr;
|
||||
struct lock **locks;
|
||||
struct passwd *pwd;
|
||||
struct group *grp;
|
||||
uid_t duid;
|
||||
gid_t dgid;
|
||||
const char *hash;
|
||||
Display *dpy;
|
||||
int s, nlocks, nscreens;
|
||||
|
||||
ARGBEGIN {
|
||||
case 'v':
|
||||
fprintf(stderr, "slock-"VERSION"\n");
|
||||
return 0;
|
||||
default:
|
||||
usage();
|
||||
} ARGEND
|
||||
|
||||
/* validate drop-user and -group */
|
||||
errno = 0;
|
||||
if (!(pwd = getpwnam(user)))
|
||||
die("slock: getpwnam %s: %s\n", user,
|
||||
errno ? strerror(errno) : "user entry not found");
|
||||
duid = pwd->pw_uid;
|
||||
errno = 0;
|
||||
if (!(grp = getgrnam(group)))
|
||||
die("slock: getgrnam %s: %s\n", group,
|
||||
errno ? strerror(errno) : "group entry not found");
|
||||
dgid = grp->gr_gid;
|
||||
|
||||
#ifdef __linux__
|
||||
dontkillme();
|
||||
#endif
|
||||
|
||||
hash = gethash();
|
||||
errno = 0;
|
||||
if (!crypt("", hash))
|
||||
die("slock: crypt: %s\n", strerror(errno));
|
||||
|
||||
if (!(dpy = XOpenDisplay(NULL)))
|
||||
die("slock: cannot open display\n");
|
||||
|
||||
/* drop privileges */
|
||||
if (setgroups(0, NULL) < 0)
|
||||
die("slock: setgroups: %s\n", strerror(errno));
|
||||
if (setgid(dgid) < 0)
|
||||
die("slock: setgid: %s\n", strerror(errno));
|
||||
if (setuid(duid) < 0)
|
||||
die("slock: setuid: %s\n", strerror(errno));
|
||||
|
||||
/*Create screenshot Image*/
|
||||
Screen *scr = ScreenOfDisplay(dpy, DefaultScreen(dpy));
|
||||
image = imlib_create_image(scr->width,scr->height);
|
||||
imlib_context_set_image(image);
|
||||
imlib_context_set_display(dpy);
|
||||
imlib_context_set_visual(DefaultVisual(dpy,0));
|
||||
imlib_context_set_drawable(RootWindow(dpy,XScreenNumberOfScreen(scr)));
|
||||
imlib_copy_drawable_to_image(0,0,0,scr->width,scr->height,0,0,1);
|
||||
|
||||
#ifdef BLUR
|
||||
|
||||
/*Blur function*/
|
||||
imlib_image_blur(blurRadius);
|
||||
#endif // BLUR
|
||||
|
||||
#ifdef PIXELATION
|
||||
/*Pixelation*/
|
||||
int width = scr->width;
|
||||
int height = scr->height;
|
||||
|
||||
for(int y = 0; y < height; y += pixelSize)
|
||||
{
|
||||
for(int x = 0; x < width; x += pixelSize)
|
||||
{
|
||||
int red = 0;
|
||||
int green = 0;
|
||||
int blue = 0;
|
||||
|
||||
Imlib_Color pixel;
|
||||
Imlib_Color* pp;
|
||||
pp = &pixel;
|
||||
for(int j = 0; j < pixelSize && j < height; j++)
|
||||
{
|
||||
for(int i = 0; i < pixelSize && i < width; i++)
|
||||
{
|
||||
imlib_image_query_pixel(x+i,y+j,pp);
|
||||
red += pixel.red;
|
||||
green += pixel.green;
|
||||
blue += pixel.blue;
|
||||
}
|
||||
}
|
||||
red /= (pixelSize*pixelSize);
|
||||
green /= (pixelSize*pixelSize);
|
||||
blue /= (pixelSize*pixelSize);
|
||||
imlib_context_set_color(red,green,blue,pixel.alpha);
|
||||
imlib_image_fill_rectangle(x,y,pixelSize,pixelSize);
|
||||
red = 0;
|
||||
green = 0;
|
||||
blue = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
/* check for Xrandr support */
|
||||
rr.active = XRRQueryExtension(dpy, &rr.evbase, &rr.errbase);
|
||||
|
||||
/* get number of screens in display "dpy" and blank them */
|
||||
nscreens = ScreenCount(dpy);
|
||||
if (!(locks = calloc(nscreens, sizeof(struct lock *))))
|
||||
die("slock: out of memory\n");
|
||||
for (nlocks = 0, s = 0; s < nscreens; s++) {
|
||||
if ((locks[s] = lockscreen(dpy, &rr, s)) != NULL)
|
||||
nlocks++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
XSync(dpy, 0);
|
||||
|
||||
/* did we manage to lock everything? */
|
||||
if (nlocks != nscreens)
|
||||
return 1;
|
||||
|
||||
/* run post-lock command */
|
||||
if (argc > 0) {
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
die("slock: fork failed: %s\n", strerror(errno));
|
||||
case 0:
|
||||
if (close(ConnectionNumber(dpy)) < 0)
|
||||
die("slock: close: %s\n", strerror(errno));
|
||||
execvp(argv[0], argv);
|
||||
fprintf(stderr, "slock: execvp %s: %s\n", argv[0], strerror(errno));
|
||||
_exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* everything is now blank. Wait for the correct password */
|
||||
readpw(dpy, &rr, locks, nscreens, hash);
|
||||
|
||||
return 0;
|
||||
}
|
2
roles/xmonad/files/slock/util.h
Normal file
2
roles/xmonad/files/slock/util.h
Normal file
@ -0,0 +1,2 @@
|
||||
#undef explicit_bzero
|
||||
void explicit_bzero(void *, size_t);
|
@ -1,7 +1,7 @@
|
||||
Config { font = "xft:Iosevka-Regular:size=11:antialias=true"
|
||||
Config { font = "Iosevka Normal 11"
|
||||
, bgColor = "#3f3f3f"
|
||||
, fgColor = "#dcdccc"
|
||||
, position = Top
|
||||
, position = TopH 22
|
||||
, border = FullB
|
||||
, borderColor = "#dcdccc"
|
||||
, lowerOnStart = True
|
||||
|
@ -1,42 +1,49 @@
|
||||
{-# LANGUAGE BlockArguments #-}
|
||||
-- Imports
|
||||
-- imports
|
||||
import XMonad
|
||||
import Data.Monoid
|
||||
import System.Exit
|
||||
import XMonad.Util.Run
|
||||
import XMonad.Util.SpawnOnce
|
||||
import XMonad.Hooks.DynamicLog
|
||||
import XMonad.Hooks.ManageDocks
|
||||
import XMonad.Layout.Spacing
|
||||
import XMonad.Layout.ThreeColumns
|
||||
import XMonad.Layout.LayoutModifier
|
||||
import XMonad.Layout.Renamed
|
||||
import XMonad.Hooks.SetWMName
|
||||
import XMonad.Util.Cursor
|
||||
import XMonad.Layout.NoBorders
|
||||
import XMonad.Layout.PerWorkspace
|
||||
import XMonad.Layout.LimitWindows
|
||||
import XMonad.Hooks.EwmhDesktops
|
||||
import XMonad.Util.EZConfig
|
||||
import XMonad.Util.NamedScratchpad
|
||||
import XMonad.Actions.TopicSpace
|
||||
import XMonad.Prompt
|
||||
import XMonad.Prompt.FuzzyMatch
|
||||
import XMonad.Prompt.Workspace
|
||||
import XMonad.Hooks.WorkspaceHistory (workspaceHistoryHook)
|
||||
import XMonad.Hooks.DynamicProperty
|
||||
import qualified XMonad.StackSet as W
|
||||
import qualified Data.Map as M
|
||||
import Text.Regex.Posix
|
||||
|
||||
import XMonad.Actions.TopicSpace (TopicConfig (..), TopicItem (..), noAction, tiDirs, tiActions, currentTopicDir, switchNthLastFocusedByScreen, switchTopic, topicNames)
|
||||
import XMonad.Actions.Search (SearchEngine, openstreetmap, hackage, wikipedia, youtube, searchEngine, promptSearch, selectSearch)
|
||||
|
||||
import XMonad.Hooks.DynamicLog (PP(..), dynamicLogWithPP, filterOutWsPP, xmobarPP, xmobarColor, wrap, shorten)
|
||||
import XMonad.Hooks.ManageDocks (ToggleStruts(..), avoidStruts, docks)
|
||||
import XMonad.Hooks.DynamicProperty (dynamicPropertyChange)
|
||||
import XMonad.Hooks.SetWMName (setWMName)
|
||||
import XMonad.Hooks.WorkspaceHistory (workspaceHistoryHook)
|
||||
|
||||
import XMonad.Layout.Spacing (Spacing, spacingRaw, Border (..))
|
||||
import XMonad.Layout.LayoutModifier (ModifiedLayout)
|
||||
import XMonad.Layout.Renamed (renamed, Rename (..))
|
||||
import XMonad.Layout.NoBorders (noBorders, smartBorders)
|
||||
|
||||
import XMonad.Util.WorkspaceCompare ( getSortByIndex, filterOutWs )
|
||||
import XMonad.Util.NamedScratchpad (NamedScratchpad (NS), customFloating, defaultFloating, namedScratchpadAction, namedScratchpadManageHook)
|
||||
import XMonad.Util.Run (proc, inProgram, termInDir, (>-$), (>->), execute, spawnPipe, spawnExternalProcess, hPutStrLn)
|
||||
import XMonad.Util.Cursor (setDefaultCursor)
|
||||
import XMonad.Util.SpawnOnce (spawnOnce)
|
||||
import XMonad.Util.EZConfig (additionalKeysP)
|
||||
|
||||
import XMonad.Prompt (XPConfig (..), mkXPrompt, mkComplFunFromList', XPPosition (..))
|
||||
import XMonad.Prompt.Workspace (Wor(..))
|
||||
import XMonad.Prompt.FuzzyMatch (fuzzyMatch, fuzzySort)
|
||||
import XMonad.Prompt.Shell (shellPrompt, unsafePrompt)
|
||||
|
||||
import Text.Regex.Posix ((=~))
|
||||
|
||||
-- variables
|
||||
myTerminal = "alacritty"
|
||||
myBrowser = "librewolf"
|
||||
myBorderWidth = 1
|
||||
myNormalBorderColor = "#dcdccc"
|
||||
myFocusedBorderColor = "#dca3a3"
|
||||
myModMask = mod4Mask
|
||||
white = "#dcdccc"
|
||||
yellow = "#efef8f"
|
||||
orange = "#ffcfaf"
|
||||
red = "#dca3a3"
|
||||
blue = "#8cd0d3"
|
||||
darkBlue = "#8c8cbc"
|
||||
green = "#7f9f7f"
|
||||
grey = "#3f3f3f"
|
||||
darkGrey = "#262626"
|
||||
|
||||
-- scratchpads
|
||||
myScratchpads :: [NamedScratchpad]
|
||||
@ -47,9 +54,11 @@ myScratchpads =
|
||||
, NS "vimwiki" "st -t vimwiki -e vwwrapper" (title =? "vimwiki") (customFloating $ W.RationalRect (1/6) (1/6) (2/3) (2/3))
|
||||
, NS "keepassxc" "keepassxc ~/dokumente/Database.kdbx" (title =? "Database.kdbx - KeePassXC" <||> title =? "Database.kdbx [Gesperrt] - KeePassXC") defaultFloating
|
||||
, NS "discord" "firejail discord" (title *!? "Discord") (customFloating $ W.RationalRect (1/10) (1/10) (8/10) (8/10))
|
||||
, NS "qalculate" "qalculate-gtk" (title =? "Qalculate!") (customFloating $ W.RationalRect (3/6) (1/6) (1/6) (1/6))
|
||||
, NS "pavucontrol" "pavucontrol" (title =? "Lautstärkeregler") (customFloating $ W.RationalRect (1/6) (1/6) (2/3) (2/3))
|
||||
]
|
||||
|
||||
-- Topic Space
|
||||
-- topic space
|
||||
topicItems :: [TopicItem]
|
||||
topicItems =
|
||||
[ noAction "1" "~/"
|
||||
@ -57,7 +66,7 @@ topicItems =
|
||||
, noAction "3" "~/"
|
||||
, noAction "4" "~/"
|
||||
, noAction "5" "~/"
|
||||
, TI "recipes" "~/projekte/recipes" (switchToLayout "Programming" *> spawnShellAndExecute "hugo server" *> proc (inProgram "librewolf") *> spawnEditor)
|
||||
, TI "recipes" "~/projekte/recipes" (switchToLayout "Programming" *> spawnShellAndExecute "hugo server" *> proc (inProgram myBrowser) *> spawnEditor)
|
||||
, TI "alkaa" "~/projekte/alkaa" (switchToLayout "Programming" *> spawnShell *> spawnEditor)
|
||||
, TI "steam" "~" (switchToLayout "Steam" *> spawn "steam")
|
||||
, TI "game" "~" (switchToLayout "Full")
|
||||
@ -69,8 +78,8 @@ myTopicConfig :: TopicConfig
|
||||
myTopicConfig = def
|
||||
{ topicDirs = tiDirs topicItems
|
||||
, topicActions = tiActions topicItems
|
||||
, defaultTopicAction = const (pure ()) -- by default, do nothing
|
||||
, defaultTopic = "1" -- fallback
|
||||
, defaultTopicAction = const (pure ())
|
||||
, defaultTopic = "1"
|
||||
}
|
||||
|
||||
spawnShell :: X ()
|
||||
@ -97,24 +106,41 @@ myWorkSpacePrompt c job = do ws <- gets (W.workspaces . windowset)
|
||||
|
||||
topicPrompt :: XPConfig
|
||||
topicPrompt = def
|
||||
{ historySize = 20 -- No history in the prompt.
|
||||
, fgColor = "#dcdccc"
|
||||
, fgHLight = "#3f3f3f"
|
||||
, bgHLight = "#dca3a3"
|
||||
, alwaysHighlight = True -- Current best match
|
||||
{ historySize = 0
|
||||
, fgColor = white
|
||||
, fgHLight = grey
|
||||
, bgHLight = red
|
||||
, alwaysHighlight = True
|
||||
, font = "xft:Iosevka-11"
|
||||
, height = 25
|
||||
, position = Top
|
||||
, promptBorderWidth = myBorderWidth -- Fit in with rest of config
|
||||
, borderColor = "#dca3a3"
|
||||
, maxComplRows = Just 5 -- Max rows to show in completion window
|
||||
, position = CenteredAt 0.45 0.3
|
||||
, promptBorderWidth = myBorderWidth
|
||||
, borderColor = red
|
||||
, maxComplRows = Just 10
|
||||
, maxComplColumns = Just 1
|
||||
, searchPredicate = fuzzyMatch
|
||||
, sorter = fuzzySort
|
||||
}
|
||||
|
||||
-- search
|
||||
searx :: SearchEngine
|
||||
searx = searchEngine "searx" "https://search.tfld.de/search?q="
|
||||
|
||||
wiktionary :: SearchEngine
|
||||
wiktionary = searchEngine "wiktionary" "https://wiktionary.org/w/index.php?search="
|
||||
|
||||
searchList :: [(String, SearchEngine)]
|
||||
searchList = [ ("o", openstreetmap)
|
||||
, ("h", hackage)
|
||||
, ("w", wikipedia)
|
||||
, ("y", youtube)
|
||||
, ("s", searx)
|
||||
, ("t", wiktionary)
|
||||
]
|
||||
|
||||
-- keybindings
|
||||
myAdditionalKeys :: [(String, X ())]
|
||||
myAdditionalKeys =
|
||||
myAdditionalKeys =
|
||||
-- xmonad specific
|
||||
[ ("M-q", spawn "xmonad --recompile; xmonad --restart")
|
||||
, ("M-S-c", kill)
|
||||
@ -129,8 +155,8 @@ myAdditionalKeys =
|
||||
, ("M-.", sendMessage ToggleStruts)
|
||||
|
||||
-- dmenu prompts
|
||||
, ("M-<Return>", spawn "dm-recent-aliases")
|
||||
, ("M-p s", spawn "dm-screenshot")
|
||||
, ("M-<Return>", spawn "dmenu_run")
|
||||
, ("M-p s", spawn "dmenu_scrreenshot")
|
||||
, ("M-p k", spawn "dm-kill")
|
||||
|
||||
-- scratchpads
|
||||
@ -141,14 +167,16 @@ myAdditionalKeys =
|
||||
|
||||
, ("M-S-a", namedScratchpadAction myScratchpads "keepassxc")
|
||||
, ("M-n", namedScratchpadAction myScratchpads "nnn")
|
||||
, ("M-s a", namedScratchpadAction myScratchpads "pavucontrol")
|
||||
, ("M-s q", namedScratchpadAction myScratchpads "qalculate")
|
||||
|
||||
-- some shortcuts for prorgrams
|
||||
, ("M-S-<Return>", spawnShell)
|
||||
, ("M-b", spawn "librewolf")
|
||||
, ("M-b", spawn myBrowser)
|
||||
|
||||
-- layout
|
||||
, ("M-t t", switchToLayout "Tall")
|
||||
, ("M-t h", switchToLayout "Programming")
|
||||
, ("M-t p", switchToLayout "Programming")
|
||||
, ("M-t f", switchToLayout "Full")
|
||||
|
||||
, ("M-S-f", withFocused $ windows . W.sink)
|
||||
@ -175,17 +203,20 @@ myAdditionalKeys =
|
||||
| (i, k) <- zip (topicNames topicItems) (map show [1 .. 5 :: Int])
|
||||
, (f, m) <- [(switchTopic myTopicConfig, ""), (windows . W.shift, "S-")]
|
||||
]
|
||||
-- Search commands
|
||||
++ [("M-d " ++ k, promptSearch topicPrompt f) | (k,f) <- searchList ]
|
||||
++ [("M-S-d " ++ k, selectSearch f) | (k,f) <- searchList ]
|
||||
|
||||
-- Layouts
|
||||
mySpacing :: Integer -> l a -> XMonad.Layout.LayoutModifier.ModifiedLayout Spacing l a
|
||||
mySpacing :: Integer -> l a -> ModifiedLayout Spacing l a
|
||||
mySpacing i = spacingRaw True (Border i i i i) True (Border i i i i) True
|
||||
|
||||
myLayout = avoidStruts $ tiling ||| hacking ||| full ||| steam
|
||||
where
|
||||
tiling = renamed [Replace "Tall"] $ smartBorders $ mySpacing 6 $ Tall 1 (3/100) (1/2)
|
||||
tiling = renamed [Replace "Tall"] $ smartBorders $ mySpacing 6 $ Tall 1 (3/100) (1/2)
|
||||
hacking = renamed [Replace "Programming"] $ smartBorders $ mySpacing 6 $ Tall 1 (3/100) (5/8)
|
||||
full = noBorders Full
|
||||
steam = renamed [Replace "Steam"] $ noBorders $ mySpacing 3 $ limitWindows 2 $ ThreeCol 1 (3/100) (5/8)
|
||||
steam = renamed [Replace "Steam"] $ noBorders $ mySpacing 3 $ Tall 1 (3/100) (6/8)
|
||||
|
||||
-- Regex lifted up to use in manageHook
|
||||
(*!?) :: Functor f => f String -> String -> f Bool
|
||||
@ -199,7 +230,7 @@ myManageHook = composeAll . concat $
|
||||
|
||||
-- Steam and games
|
||||
, [ className =? "Steam" --> doShift "steam" ]
|
||||
, [ ( className =? "Steam" <&&> title *!? "Friends List" <||> title *!? "News" ) --> doF W.swapDown ]
|
||||
, [ (title *!? "Friends List" <||> title *!? "News" ) --> doF W.swapDown ]
|
||||
, [ title =? t <&&> title *!? t --> doShift "game" | t <- myGames ]
|
||||
|
||||
-- float specific classes
|
||||
@ -213,15 +244,6 @@ myManageHook = composeAll . concat $
|
||||
myFloatingClasses = ["Gimp", "Origin"]
|
||||
myGames = ["Grim Dawn", "Der Herr der Ringe Online™", "Dota 2", "Project Zomboid", "Valheim", "Factorio", "Path of Exile", "Paradox Launcher", "Europa Universalis IV", "Bannerlord"]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
-- Event handling
|
||||
|
||||
-- * EwmhDesktops users should change this to ewmhDesktopsEventHook
|
||||
--
|
||||
-- Defines a custom handler function for X Events. The function should
|
||||
-- return (All True) if the default handler is to be run afterwards. To
|
||||
-- combine event hooks use mappend or mconcat from Data.Monoid.
|
||||
--
|
||||
myEventHook = dynamicPropertyChange "WM_NAME" (title =? "Database.kdbx - KeePassXC" <||> title =? "Database.kdbx [Gesperrt] - KeePassXC" --> floating)
|
||||
where floating = customFloating $ W.RationalRect (1/8) (1/8) (3/4) (3/4)
|
||||
|
||||
@ -229,30 +251,28 @@ myEventHook = dynamicPropertyChange "WM_NAME" (title =? "Database.kdbx - KeePass
|
||||
myStartupHook = do
|
||||
setWMName "LG3D"
|
||||
setDefaultCursor xC_left_ptr
|
||||
spawnOnce("redshift -c /home/max/.config/redshift/redshiftrc")
|
||||
spawnOnce("feh --bg-fill ~/bilder/bg.jpg")
|
||||
spawnOnce("/usr/bin/syncthing -no-browser -logfile=default")
|
||||
|
||||
spawnOnce "redshift -c /home/max/.config/redshift/redshiftrc"
|
||||
spawnOnce "feh --bg-fill ~/bilder/bg.jpg"
|
||||
spawnOnce "/usr/bin/syncthing -no-browser -logfile=default"
|
||||
|
||||
-- Main
|
||||
main = do
|
||||
xmproc <- spawnPipe "xmobar /home/max/.config/xmobar/xmobarrc"
|
||||
xmonad $ spawnExternalProcess def $ docks $ def {
|
||||
-- simple stuff
|
||||
terminal = myTerminal,
|
||||
borderWidth = myBorderWidth,
|
||||
modMask = myModMask,
|
||||
workspaces = topicNames topicItems,
|
||||
normalBorderColor = myNormalBorderColor,
|
||||
focusedBorderColor = myFocusedBorderColor,
|
||||
-- hooks, layouts
|
||||
normalBorderColor = white,
|
||||
focusedBorderColor = red,
|
||||
layoutHook = myLayout,
|
||||
manageHook = myManageHook,
|
||||
handleEventHook = myEventHook,
|
||||
logHook = workspaceHistoryHook >> (dynamicLogWithPP $ filterOutWsPP ["NSP"] $ xmobarPP {
|
||||
ppCurrent = xmobarColor "#dca3a3" "" . wrap "[ " " ]",
|
||||
ppHidden = xmobarColor "#8cd0d3" "",
|
||||
ppLayout = xmobarColor "#8c8cbc" "",
|
||||
ppTitle = xmobarColor "#ffcfaf" "" . shorten 100,
|
||||
logHook = workspaceHistoryHook >> dynamicLogWithPP (filterOutWsPP ["NSP"] $ xmobarPP {
|
||||
ppCurrent = xmobarColor red "" . wrap "[ " " ]",
|
||||
ppHidden = xmobarColor blue "",
|
||||
ppLayout = xmobarColor darkBlue "",
|
||||
ppTitle = xmobarColor orange "" . shorten 90,
|
||||
ppSep = " | ",
|
||||
ppOutput = hPutStrLn xmproc
|
||||
}),
|
||||
|
@ -42,6 +42,8 @@ import Text.Regex.Posix
|
||||
import XMonad.Util.WorkspaceCompare ( getSortByIndex, filterOutWs )
|
||||
import Data.Maybe (fromMaybe)
|
||||
|
||||
import qualified XMonad.Actions.Search as S
|
||||
import qualified XMonad.Prompt as P
|
||||
|
||||
-- colours
|
||||
white :: String = "#dcdccc"
|
||||
@ -67,6 +69,7 @@ myScratchpads =
|
||||
, NS "vimwiki" "alacritty -t vimwiki -e vwwrapper" (title =? "vimwiki") (customFloating $ W.RationalRect (1/6) (1/6) (2/3) (2/3))
|
||||
, NS "pavucontrol" "pavucontrol" (title =? "Lautstärkeregler") (customFloating $ W.RationalRect (1/6) (1/6) (2/3) (2/3))
|
||||
, NS "cmus" "alacritty -t 'cmus' -e cmus" (title =? "cmus") (customFloating $ W.RationalRect (1/6) (1/6) (2/3) (2/3))
|
||||
, NS "qalculate" "qalculate-gtk" (title =? "Qalculate!") (customFloating $ W.RationalRect (3/6) (1/6) (1/6) (1/6))
|
||||
]
|
||||
|
||||
-- Topic Space
|
||||
@ -137,6 +140,20 @@ topicPrompt = def
|
||||
, sorter = fuzzySort
|
||||
}
|
||||
|
||||
searx :: S.SearchEngine
|
||||
searx = S.searchEngine "searx" "https://search.tfld.de/search?q="
|
||||
|
||||
wiktionary :: S.SearchEngine
|
||||
wiktionary = S.searchEngine "wiktionary" "https://wiktionary.org/w/index.php?search="
|
||||
|
||||
searchList :: [(String, S.SearchEngine)]
|
||||
searchList = [ ("o", S.openstreetmap)
|
||||
, ("h", S.hackage)
|
||||
, ("w", S.wikipedia)
|
||||
, ("y", S.youtube)
|
||||
, ("s", searx)
|
||||
, ("t", wiktionary)
|
||||
]
|
||||
|
||||
-- custom keybinds
|
||||
myAdditionalKeys :: [(String, X ())]
|
||||
@ -155,10 +172,9 @@ myAdditionalKeys =
|
||||
, ("M-.", sendMessage ToggleStruts)
|
||||
|
||||
-- dmenu prompts
|
||||
, ("M-<Return>", spawn "dm-recent-aliases")
|
||||
, ("M-p s", spawn "dm-screenshot")
|
||||
, ("M-<Return>", spawn "dmenu_run")
|
||||
, ("M-p s", spawn "dmenu_screenshot")
|
||||
, ("M-p k", spawn "dm-kill")
|
||||
, ("M-p p", shellPrompt topicPrompt)
|
||||
|
||||
-- scratchpads
|
||||
, ("M-n", namedScratchpadAction myScratchpads "nnn")
|
||||
@ -166,6 +182,7 @@ myAdditionalKeys =
|
||||
, ("M-s v", namedScratchpadAction myScratchpads "vimwiki")
|
||||
, ("M-s a", namedScratchpadAction myScratchpads "pavucontrol")
|
||||
, ("M-s c", namedScratchpadAction myScratchpads "cmus")
|
||||
, ("M-s q", namedScratchpadAction myScratchpads "qalculate")
|
||||
|
||||
-- open terminal
|
||||
, ("M-S-<Return>", spawnShell)
|
||||
@ -199,6 +216,10 @@ myAdditionalKeys =
|
||||
| (i, k) <- zip (topicNames topicItems) (map show [1 .. 5 :: Int])
|
||||
, (f, m) <- [(switchTopic myTopicConfig, ""), (windows . W.shift, "S-")]
|
||||
]
|
||||
-- Search commands
|
||||
++ [("M-d " ++ k, S.promptSearch topicPrompt f) | (k,f) <- searchList ]
|
||||
++ [("M-S-d " ++ k, S.selectSearch f) | (k,f) <- searchList ]
|
||||
|
||||
|
||||
-- Layouts
|
||||
mySpacing :: Integer -> l a -> XMonad.Layout.LayoutModifier.ModifiedLayout Spacing l a
|
||||
@ -269,7 +290,7 @@ myStartupHook = do
|
||||
main = do
|
||||
xmproc0 <- spawnPipe "xmobar -x 0 /home/max/.config/xmobar/xmobarrc"
|
||||
xmproc1 <- spawnPipe "xmobar -x 1 /home/max/.config/xmobar/xmobarrc"
|
||||
xmonad $ spawnExternalProcess def $ docks def {
|
||||
xmonad $ ewmh . spawnExternalProcess def $ docks def {
|
||||
-- simple stuff
|
||||
terminal = myTerminal,
|
||||
borderWidth = myBorderWidth,
|
||||
|
@ -9,9 +9,16 @@
|
||||
- dunst
|
||||
- redshift
|
||||
- cmus
|
||||
- lightdm
|
||||
- lightdm-gtk-greeter
|
||||
- nnn
|
||||
- tar
|
||||
- zip
|
||||
- unzip
|
||||
- unrar
|
||||
state: present
|
||||
become: true
|
||||
tags: pc
|
||||
tags: [pc, setup]
|
||||
|
||||
- name: Install t460p specifig packages
|
||||
ansible.builtin.package:
|
||||
@ -20,10 +27,35 @@
|
||||
- pamixer
|
||||
- brightnessctl
|
||||
state: present
|
||||
tags: t460p
|
||||
tags: [t460p, setup]
|
||||
|
||||
# - name: Build and install custom st, dmenu and slock
|
||||
# tags: pc
|
||||
- name: Build and install dmenu
|
||||
community.general.make:
|
||||
chdir: "{{ role_path }}/files/dmenu"
|
||||
target: install
|
||||
become: true
|
||||
tags: [pc, setup]
|
||||
|
||||
- name: Cleanup built dmenu artifacts
|
||||
community.general.make:
|
||||
chdir: "{{ role_path }}/files/dmenu"
|
||||
target: clean
|
||||
become: true
|
||||
tags: [pc, setup]
|
||||
|
||||
- name: Build and install slock
|
||||
community.general.make:
|
||||
chdir: "{{ role_path }}/files/slock"
|
||||
target: install
|
||||
become: true
|
||||
tags: [pc, setup]
|
||||
|
||||
- name: Cleanup built slock artifacts
|
||||
community.general.make:
|
||||
chdir: "{{ role_path }}/files/slock"
|
||||
target: clean
|
||||
become: true
|
||||
tags: [pc, setup]
|
||||
|
||||
- name: Create config directories
|
||||
ansible.builtin.file:
|
||||
@ -35,7 +67,7 @@
|
||||
- ~/.config/xmobar
|
||||
- ~/.config/dunst
|
||||
- ~/.config/cmus
|
||||
tags: pc
|
||||
tags: [pc, setup]
|
||||
|
||||
- name: Copy over alacritty config
|
||||
ansible.builtin.copy:
|
||||
@ -51,6 +83,13 @@
|
||||
mode: '0644'
|
||||
tags: pc
|
||||
|
||||
- name: Copy over dircolours
|
||||
ansible.builtin.copy:
|
||||
src: dircolours
|
||||
dest: ~/.config/dircolours
|
||||
mode: '0644'
|
||||
tags: pc
|
||||
|
||||
- name: Copy over cmus config
|
||||
ansible.builtin.copy:
|
||||
src: "{{ item }}"
|
||||
@ -59,6 +98,28 @@
|
||||
with_fileglob: "cmus/*"
|
||||
tags: pc
|
||||
|
||||
- name: Create nnn config directory
|
||||
ansible.builtin.file:
|
||||
path: "~/.config/nnn"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
tags: [pc, setup]
|
||||
|
||||
- name: Clone nnn repository into temp
|
||||
ansible.builtin.git:
|
||||
repo: https://github.com/jarun/nnn.git
|
||||
force: true
|
||||
dest: /tmp/nnn
|
||||
tags: [pc, setup]
|
||||
|
||||
- name: Move nnn plugins into right place
|
||||
ansible.builtin.copy:
|
||||
remote_src: true
|
||||
src: /tmp/nnn/plugins
|
||||
dest: ~/.config/nnn/plugins
|
||||
mode: '0755'
|
||||
tags: [pc, setup]
|
||||
|
||||
- name: Copy over T460p config files
|
||||
ansible.builtin.copy:
|
||||
src: "{{ item.src }}"
|
||||
@ -67,6 +128,8 @@
|
||||
with_items:
|
||||
- { src: xmonad_t460p.hs, dest: ~/.config/xmonad/xmonad.hs }
|
||||
- { src: xmobarrc_t460p, dest: ~/.config/xmobar/xmobarrc }
|
||||
- { src: bashrc_t460p, dest: ~/.bashrc }
|
||||
- { src: profile_t460p, dest: ~/.profile }
|
||||
tags: t460p
|
||||
|
||||
- name: Copy over qwerty config files
|
||||
@ -78,3 +141,10 @@
|
||||
- { src: xmonad_qwerty.hs, dest: ~/.config/xmonad/xmonad.hs }
|
||||
- { src: xmobarrc_qwerty, dest: ~/.config/xmobar/xmobarrc }
|
||||
tags: qwerty
|
||||
|
||||
- name: Enable Lightdm
|
||||
ansible.builtin.service:
|
||||
name: lightdm
|
||||
state: started
|
||||
enabled: true
|
||||
tags: [pc, setup]
|
||||
|
Loading…
Reference in New Issue
Block a user