Compare commits
128 commits
applay-key
...
master
Author | SHA1 | Date | |
---|---|---|---|
2a7e15ea63 | |||
23e9813c88 | |||
9b9fd452f2 | |||
faa9d49509 | |||
2c9716c05f | |||
bec37f54b7 | |||
6bfa127871 | |||
43871cc01e | |||
6a38e1171d | |||
3ad6c14c6d | |||
0dce78d77f | |||
ab0aea1d09 | |||
c09bde1f8d | |||
7ddb9c82bf | |||
|
c282e960fc | ||
|
9df191bd1f | ||
|
306b3149d8 | ||
|
97133f2383 | ||
dd8295212a | |||
46705d8d43 | |||
97055fdf2f | |||
1b6ddb9726 | |||
139e337b91 | |||
1adcb169c3 | |||
a6cec51475 | |||
5e4a0bb79b | |||
8fbfe9006d | |||
f8a0930e65 | |||
d785d51e2d | |||
d86ffd3813 | |||
feb819c903 | |||
453b07f4d6 | |||
f367518443 | |||
fa1aa3e444 | |||
8f4a20dd4e | |||
38d85133c4 | |||
5e289b8438 | |||
952526f495 | |||
fd829d6d88 | |||
8d49ee09de | |||
540a9eff7f | |||
89adca6574 | |||
53da160f0a | |||
7208347361 | |||
7baddde619 | |||
f3b2844966 | |||
a86f296efc | |||
0a99c90162 | |||
75ec761539 | |||
8c61745f12 | |||
55540e5b4f | |||
cfaef82513 | |||
0aa1ecc3ef | |||
7d4a8b9999 | |||
248f2db087 | |||
a23133608a | |||
639c18a095 | |||
19e9f24391 | |||
cd8f5d4709 | |||
|
c3cf0921ca | ||
3d3786d1e6 | |||
706bf5e4fb | |||
cb6f0a2a8d | |||
0a5df92d57 | |||
8b3f357191 | |||
4cf5dccdf0 | |||
|
0f989c8121 | ||
e18c162967 | |||
989751701d | |||
37ce41dd6d | |||
5bb7487b40 | |||
20b68c338c | |||
|
0f72e5c31c | ||
66047b2404 | |||
40b65a0171 | |||
5c398adf74 | |||
a7d9d11968 | |||
99f899be42 | |||
50e80e07ed | |||
46dc9cead8 | |||
6eb5fee7de | |||
6099f19a49 | |||
44f85c76ec | |||
0f156ff3a9 | |||
|
ba56fe9fea | ||
59fa9423b5 | |||
c3cc2c4567 | |||
b1e403689f | |||
|
50ad171eea | ||
9cf8ec6fa8 | |||
|
970f376973 | ||
3d6ccec653 | |||
|
c2b748e793 | ||
|
84d7322113 | ||
|
5799dd1fca | ||
|
44adafe006 | ||
|
a859676ead | ||
|
e0dee91145 | ||
|
5e76e7e21d | ||
eb4c01d478 | |||
|
5b2e5e7a40 | ||
|
786f6e2a6f | ||
202d939a66 | |||
4ecc0d3c9e | |||
|
d1afe016d7 | ||
|
55e33220a7 | ||
9260a252e1 | |||
e19cff5a96 | |||
|
1ef2014240 | ||
1e36145313 | |||
c3c5da0ae4 | |||
0d2fe14e25 | |||
fbaab1bbe3 | |||
aa5d8a8c22 | |||
5d3af206be | |||
b726853f33 | |||
138bb0bb41 | |||
0c224e26f6 | |||
11f2af9ce1 | |||
25a26c2a9e | |||
214668b975 | |||
bf3ce283ca | |||
8eafb095d2 | |||
71981a7941 | |||
2d0dd05de5 | |||
c089ee61e3 | |||
6288fd7d0c | |||
|
e03248a4d5 |
65 changed files with 3913 additions and 6351 deletions
17
.github/workflows/bitbucket-mirror.yml
vendored
Normal file
17
.github/workflows/bitbucket-mirror.yml
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
name: Mirror the repo to bitbucket
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
bitbucket-mirror:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: mirror in bitbucket
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: yesolutions/mirror-action@master
|
||||||
|
with:
|
||||||
|
REMOTE: 'https://anas-elgarhy@bitbucket.org/anas_elgarhy/archy-dwm.git'
|
||||||
|
REMOTE_NAME: bitbucket
|
||||||
|
GIT_USERNAME: anas_elgarhy
|
||||||
|
GIT_PASSWORD: ${{ secrets.BITBUCKET_TOKEN }}
|
2
.github/workflows/c-cpp.yml
vendored
2
.github/workflows/c-cpp.yml
vendored
|
@ -12,7 +12,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- name: install libs
|
- name: install libs
|
||||||
run: sudo apt-get install libxinerama1 libxinerama-dev
|
run: sudo apt-get install libxinerama1 libxinerama-dev
|
||||||
- name: make install test
|
- name: make install test
|
||||||
|
|
17
.github/workflows/codeberg-mirror.yml
vendored
Normal file
17
.github/workflows/codeberg-mirror.yml
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
name: Mirror the repo to codeberg
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
codeberg-mirror:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: mirror in codeberg
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: yesolutions/mirror-action@master
|
||||||
|
with:
|
||||||
|
REMOTE: 'https://codeberg.org/archy-linux/archy-dwm.git'
|
||||||
|
REMOTE_NAME: codeberg
|
||||||
|
GIT_USERNAME: anas-elgarhy
|
||||||
|
GIT_PASSWORD: ${{ secrets.CODEBERG_TOKEN }}
|
17
.github/workflows/disroot-mirror.yml
vendored
Normal file
17
.github/workflows/disroot-mirror.yml
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
name: Mirror the repo to disroot
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
disroot-mirror:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: mirror in git.disroot
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: yesolutions/mirror-action@master
|
||||||
|
with:
|
||||||
|
REMOTE: 'https://git.disroot.org/archy-linux/archy-dwm.git'
|
||||||
|
REMOTE_NAME: disroot
|
||||||
|
GIT_USERNAME: anas-elgarhy
|
||||||
|
GIT_PASSWORD: ${{ secrets.DISROOT_TOKEN }}
|
17
.github/workflows/gitdab-mirror.yml
vendored
Normal file
17
.github/workflows/gitdab-mirror.yml
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
name: Mirror the repo to Gitdab
|
||||||
|
on: [ push ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
gitdab-mirror:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: mirror in Gitdab
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: yesolutions/mirror-action@master
|
||||||
|
with:
|
||||||
|
REMOTE: 'https://gitdab.com/archy-linux/archy-dwm.git'
|
||||||
|
REMOTE_NAME: gitdab
|
||||||
|
GIT_USERNAME: anas-elgarhy
|
||||||
|
GIT_PASSWORD: ${{ secrets.GITDAB_TOKEN }}
|
17
.github/workflows/gitea-mirror.yml
vendored
Normal file
17
.github/workflows/gitea-mirror.yml
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
name: Mirror the repo to Gitea
|
||||||
|
on: [ push ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
gitea-mirror:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: mirror in Gitea
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: yesolutions/mirror-action@master
|
||||||
|
with:
|
||||||
|
REMOTE: 'https://gitea.com/archy-linux/archy-dwm.git'
|
||||||
|
REMOTE_NAME: gitea
|
||||||
|
GIT_USERNAME: anas-elgarhy
|
||||||
|
GIT_PASSWORD: ${{ secrets.GITEA_TOKEN }}
|
16
.github/workflows/gitlab-mirror.yml
vendored
Normal file
16
.github/workflows/gitlab-mirror.yml
vendored
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
name: Mirror the repo to gitlab
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
gitlab-mirror:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: mirror in gitlab
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: yesolutions/mirror-action@master
|
||||||
|
with:
|
||||||
|
REMOTE: 'https://gitlab.com/archy-linux/archy-dwm'
|
||||||
|
GIT_USERNAME: Anas-Elgarhy
|
||||||
|
GIT_PASSWORD: ${{ secrets.GITLAP_TOKEN }}
|
39
.github/workflows/mirror.yml
vendored
39
.github/workflows/mirror.yml
vendored
|
@ -1,39 +0,0 @@
|
||||||
# This is a basic workflow that is manually triggered
|
|
||||||
name: Mirror repo
|
|
||||||
on: [push]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
mirror:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: mirror in gitlab
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- uses: yesolutions/mirror-action@master
|
|
||||||
with:
|
|
||||||
REMOTE: 'https://gitlab.com/anas-elgarhy/dwm-anas.git'
|
|
||||||
GIT_USERNAME: Anas-Elgarhy
|
|
||||||
GIT_PASSWORD: ${{ secrets.GITLAP_TOKEN }}
|
|
||||||
|
|
||||||
# - name: mirror in bitbucket
|
|
||||||
# uses: actions/checkout@v3
|
|
||||||
# with:
|
|
||||||
# fetch-depth: 0
|
|
||||||
# - uses: yesolutions/mirror-action@master
|
|
||||||
# with:
|
|
||||||
# REMOTE: 'https://anas_elgarhy@bitbucket.org/anas_elgarhy/dwm-anas.git'
|
|
||||||
# REMOTE_NAME: bitbucket
|
|
||||||
# GIT_USERNAME: anas_elgarhy
|
|
||||||
# GIT_PASSWORD: ${{ secrets.BITBUCKET_TOKEN }}
|
|
||||||
|
|
||||||
- name: mirror in codeberg
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- uses: yesolutions/mirror-action@master
|
|
||||||
with:
|
|
||||||
REMOTE: 'https://codeberg.org/anas-elgarhy/dwm-anas.git'
|
|
||||||
REMOTE_NAME: codeberg
|
|
||||||
GIT_USERNAME: anas-elgarhy
|
|
||||||
GIT_PASSWORD: ${{ secrets.CODEBERG_TOKEN }}
|
|
17
.github/workflows/pagure-mirror.yml
vendored
Normal file
17
.github/workflows/pagure-mirror.yml
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
name: Mirror the repo to pagure
|
||||||
|
on: [ push ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
gitdab-mirror:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: mirror in Gitdab
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: yesolutions/mirror-action@master
|
||||||
|
with:
|
||||||
|
REMOTE: 'https://gitdab.com/archy-linux/archy-dwm.git'
|
||||||
|
REMOTE_NAME: gitdab
|
||||||
|
GIT_USERNAME: anas-elgarhy
|
||||||
|
|
69
.gitignore
vendored
69
.gitignore
vendored
|
@ -1,3 +1,68 @@
|
||||||
*.o
|
### C template
|
||||||
dwm
|
# Prerequisites
|
||||||
|
*.d
|
||||||
|
|
||||||
|
# Object files
|
||||||
|
*.o
|
||||||
|
*.ko
|
||||||
|
*.obj
|
||||||
|
*.elf
|
||||||
|
|
||||||
|
# Linker output
|
||||||
|
*.ilk
|
||||||
|
*.map
|
||||||
|
*.exp
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
*.lib
|
||||||
|
*.a
|
||||||
|
*.la
|
||||||
|
*.lo
|
||||||
|
|
||||||
|
# Shared objects (inc. Windows DLLs)
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
*.i*86
|
||||||
|
*.x86_64
|
||||||
|
*.hex
|
||||||
|
|
||||||
|
# Debug files
|
||||||
|
*.dSYM/
|
||||||
|
*.su
|
||||||
|
*.idb
|
||||||
|
*.pdb
|
||||||
|
|
||||||
|
# Kernel Module Compile Results
|
||||||
|
*.mod*
|
||||||
|
*.cmd
|
||||||
|
.tmp_versions/
|
||||||
|
modules.order
|
||||||
|
Module.symvers
|
||||||
|
Mkfile.old
|
||||||
|
dkms.conf
|
||||||
|
|
||||||
|
### CMake template
|
||||||
|
CMakeLists.txt.user
|
||||||
|
CMakeCache.txt
|
||||||
|
CMakeFiles
|
||||||
|
CMakeScripts
|
||||||
|
Testing
|
||||||
|
cmake_install.cmake
|
||||||
|
install_manifest.txt
|
||||||
|
compile_commands.json
|
||||||
|
CTestTestfile.cmake
|
||||||
|
_deps
|
||||||
|
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
|
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[submodule "archpackage/archy-dwm/archy-dwm-aur"]
|
||||||
|
path = archpackage/archy-dwm/archy-dwm-aur
|
||||||
|
url = ssh://aur@aur.archlinux.org/archy-dwm.git
|
||||||
|
[submodule "archpackage/archy-dwm-git/archy-dwm-git-aur"]
|
||||||
|
path = archpackage/archy-dwm-git/archy-dwm-git-aur
|
||||||
|
url = ssh://aur@aur.archlinux.org/archy-dwm-git.git
|
7
.mergify.yml
Normal file
7
.mergify.yml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
pull_request_rules:
|
||||||
|
- name: Automatic merge on approval
|
||||||
|
conditions:
|
||||||
|
- "#approved-reviews-by>=1"
|
||||||
|
actions:
|
||||||
|
merge:
|
||||||
|
method: merge
|
72
Makefile
Normal file
72
Makefile
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
# dwm - dynamic window manager
|
||||||
|
# See LICENSE file for copyright and license details.
|
||||||
|
|
||||||
|
include config.mk
|
||||||
|
|
||||||
|
SRC = src/drw.c src/archy_dwm.c src/util.c
|
||||||
|
OBJ_DIR = build
|
||||||
|
OBJ = ${SRC:%.c=$(OBJ_DIR)/%.o}
|
||||||
|
BUILD_DIR = ${OBJ_DIR}/archy-dwm
|
||||||
|
|
||||||
|
all: options ${BUILD_DIR}
|
||||||
|
|
||||||
|
options:
|
||||||
|
@echo archy-dwm build options:
|
||||||
|
@echo "CFLAGS = ${CFLAGS}"
|
||||||
|
@echo "LDFLAGS = ${LDFLAGS}"
|
||||||
|
@echo "CC = ${CC}"
|
||||||
|
|
||||||
|
${OBJ_DIR}/%.o: %.c
|
||||||
|
mkdir -p $(@D)
|
||||||
|
${CC} -c ${CFLAGS} $< -o $@
|
||||||
|
|
||||||
|
${OBJ}: src/config/config.h config.mk
|
||||||
|
|
||||||
|
config.h:
|
||||||
|
cp config.def.h $@
|
||||||
|
|
||||||
|
${BUILD_DIR}: ${OBJ}
|
||||||
|
${CC} -o $@ ${OBJ} ${LDFLAGS}
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf ${OBJ_DIR}
|
||||||
|
|
||||||
|
dist: ${BUILD_DIR} archy-dwm.desktop
|
||||||
|
mkdir -p archy-dwm_${VERSION}
|
||||||
|
cp -R LICENSE README.md ${BUILD_DIR} ${OBJ_DIR}/archy-dwm.desktop archy-dwm.1 dwm.png archy-dwm_${VERSION}
|
||||||
|
tar -cf archy-dwm_${VERSION}.tar archy-dwm_${VERSION}
|
||||||
|
gzip archy-dwm_${VERSION}.tar
|
||||||
|
rm -rf archy-dwm_${VERSION}
|
||||||
|
mkdir -p dist
|
||||||
|
mv archy-dwm_${VERSION}.tar.gz dist
|
||||||
|
echo "The tarball is ready."
|
||||||
|
printf "Tarball size: %s\n" $$(du -h dist/archy-dwm_${VERSION}.tar.gz | cut -f1)
|
||||||
|
printf "Tarball hash: %s\n" $$(sha256sum dist/archy-dwm_${VERSION}.tar.gz)
|
||||||
|
|
||||||
|
install: all
|
||||||
|
mkdir -p ${DESTDIR}${PREFIX}/bin
|
||||||
|
cp -f ${BUILD_DIR} ${DESTDIR}${PREFIX}/bin
|
||||||
|
chmod 755 ${DESTDIR}${PREFIX}/bin/archy-dwm
|
||||||
|
mkdir -p ${DESTDIR}${MANPREFIX}/man1
|
||||||
|
sed "s/VERSION/${VERSION}/g" < archy-dwm.1 > ${DESTDIR}${MANPREFIX}/man1/archy-dwm.1
|
||||||
|
chmod 644 ${DESTDIR}${MANPREFIX}/man1/archy-dwm.1
|
||||||
|
|
||||||
|
archy-dwm.desktop:
|
||||||
|
mkdir -p "$(OBJ_DIR)"
|
||||||
|
echo "[Desktop Entry]" > "$(OBJ_DIR)/archy-dwm.desktop"
|
||||||
|
echo "Type=XSession" >> "$(OBJ_DIR)/archy-dwm.desktop"
|
||||||
|
echo "Exec=$(DESTDIR)$(PREFIX)/bin/archy-dwm" >> "$(OBJ_DIR)/archy-dwm.desktop"
|
||||||
|
echo "DesktopNames=archy-dwm" >> "$(OBJ_DIR)/archy-dwm.desktop"
|
||||||
|
echo "Name=archy-dwm" >> "$(OBJ_DIR)/archy-dwm.desktop"
|
||||||
|
echo "Comment=\"A dynamic window manager for X\"" >> "$(OBJ_DIR)/archy-dwm.desktop"
|
||||||
|
|
||||||
|
desktop: archy-dwm.desktop
|
||||||
|
mkdir -p ${DESTDIR}${PREFIX}/share/xsessions
|
||||||
|
cp "$(OBJ_DIR)/archy-dwm.desktop" ${DESTDIR}${PREFIX}/share/xsessions/archy-dwm.desktop
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
rm -f ${DESTDIR}${PREFIX}/bin/archy-dwm \
|
||||||
|
${DESTDIR}${MANPREFIX}/man1/archy-dwm.1 \
|
||||||
|
${DESTDIR}${PREFIX}/share/xsessions/archy-dwm.desktop
|
||||||
|
|
||||||
|
.PHONY: all options clean dist install uninstall
|
48
README
48
README
|
@ -1,48 +0,0 @@
|
||||||
dwm - dynamic window manager
|
|
||||||
============================
|
|
||||||
dwm is an extremely fast, small, and dynamic window manager for X.
|
|
||||||
|
|
||||||
|
|
||||||
Requirements
|
|
||||||
------------
|
|
||||||
In order to build dwm you need the Xlib header files.
|
|
||||||
|
|
||||||
|
|
||||||
Installation
|
|
||||||
------------
|
|
||||||
Edit config.mk to match your local setup (dwm is installed into
|
|
||||||
the /usr/local namespace by default).
|
|
||||||
|
|
||||||
Afterwards enter the following command to build and install dwm (if
|
|
||||||
necessary as root):
|
|
||||||
|
|
||||||
make clean install
|
|
||||||
|
|
||||||
|
|
||||||
Running dwm
|
|
||||||
-----------
|
|
||||||
Add the following line to your .xinitrc to start dwm using startx:
|
|
||||||
|
|
||||||
exec dwm
|
|
||||||
|
|
||||||
In order to connect dwm to a specific display, make sure that
|
|
||||||
the DISPLAY environment variable is set correctly, e.g.:
|
|
||||||
|
|
||||||
DISPLAY=foo.bar:1 exec dwm
|
|
||||||
|
|
||||||
(This will start dwm on display :1 of the host foo.bar.)
|
|
||||||
|
|
||||||
In order to display status info in the bar, you can do something
|
|
||||||
like this in your .xinitrc:
|
|
||||||
|
|
||||||
while xsetroot -name "`date` `uptime | sed 's/.*,//'`"
|
|
||||||
do
|
|
||||||
sleep 1
|
|
||||||
done &
|
|
||||||
exec dwm
|
|
||||||
|
|
||||||
|
|
||||||
Configuration
|
|
||||||
-------------
|
|
||||||
The configuration of dwm is done by creating a custom config.h
|
|
||||||
and (re)compiling the source code.
|
|
144
README.md
144
README.md
|
@ -1,141 +1,35 @@
|
||||||
# Anas Elgarhy's dwm
|
# archy-dwm
|
||||||
## My fork from dwm 🍴, with a lot of beautiful patches 🥰
|
## DWM but cleaner and more usable
|
||||||
|
|
||||||
![dwm screenshot](./screenshots/dwm-6.3-0.1.0.png)
|
### Patches
|
||||||
![dwm and 2 alacritty](./screenshots/dwm_bpytop_and_ufetch_tile_layout-6.3-0.1.0.png)
|
|
||||||
![dwm and alacritty](./screenshots/dwm_alacritty-6.3-0.1.0.png)
|
|
||||||
![dwm and alacritty and cmus and cava](./screenshots/dwm_alacritty_cmus_cava-6.3-0.1.1.png)
|
|
||||||
|
|
||||||
### Applayed patches:
|
|
||||||
- [alwayscenter](https://dwm.suckless.org/patches/alwayscenter)
|
- [alwayscenter](https://dwm.suckless.org/patches/alwayscenter)
|
||||||
- [cool autostart](https://dwm.suckless.org/patches/cool_autostart)
|
- [cool autostart](https://dwm.suckless.org/patches/cool_autostart)
|
||||||
- [fullscreen](https://dwm.suckless.org/patches/fullscreen)
|
- [fullscreen](https://dwm.suckless.org/patches/fullscreen)
|
||||||
- [gridmode](https://dwm.suckless.org/patches/gridmode)
|
- [gridmode](https://dwm.suckless.org/patches/gridmode)
|
||||||
- [keychord](https://dwm.suckless.org/patches/keychord)
|
|
||||||
- [movestack](https://dwm.suckless.org/patches/movestack)
|
- [movestack](https://dwm.suckless.org/patches/movestack)
|
||||||
- [pertag](https://dwm.suckless.org/patches/pertag)
|
- [pertag](https://dwm.suckless.org/patches/pertag)
|
||||||
- [systray](https://dwm.suckless.org/patches/systray)
|
- [systray](https://dwm.suckless.org/patches/systray)
|
||||||
- [sticky](https://dwm.suckless.org/patches/sticky)
|
- [sticky](https://dwm.suckless.org/patches/sticky)
|
||||||
- [noborder](https://dwm.suckless.org/patches/noborder)
|
- [noborder](https://dwm.suckless.org/patches/noborder)
|
||||||
|
- [notitle](https://dwm.suckless.org/patches/notitle)
|
||||||
- [fibonacci layouts](https://dwm.suckless.org/patches/fibonacci)
|
- [fibonacci layouts](https://dwm.suckless.org/patches/fibonacci)
|
||||||
- [centeredmaster](https://dwm.suckless.org/patches/centeredmaster)
|
- [centeredmaster](https://dwm.suckless.org/patches/centeredmaster)
|
||||||
|
|
||||||
### Keys
|
### Dependencies
|
||||||
| Keys | Function |
|
- `libxinerama-dev`
|
||||||
|--------------------------------|-----------------------------------------------------------------------|
|
|
||||||
| modkey + shift + d | Open dmenu (launcher) |
|
|
||||||
| modkey + shift + ctrl + d | Open rofi launcher (small size) |
|
|
||||||
| modkey + enter | Launche the main terminal (alacritty by default) |
|
|
||||||
| modkey + t -> a | Launche the alacritty terminal |
|
|
||||||
| modkey + t -> shift + a | Launche the alacritty terminal with tmux |
|
|
||||||
| modkey + t -> k | Launche the kitty terminal |
|
|
||||||
| modkey + t -> shift + k | Launche the kitty terminal with tmux |
|
|
||||||
| modkey + shift + f -> g | Launche the GUI file manger (pcmanfm by default) |
|
|
||||||
| modkey + shift + f -> f | Launche rofi file file browser (small size) |
|
|
||||||
| modkey + shift + f -> r | Launche ranger in the main terminal |
|
|
||||||
| modkey + w -> g | Launche google chrome browser |
|
|
||||||
| modkey + w -> t | Launche tor browser |
|
|
||||||
| modkey + c -> d | Launche discord |
|
|
||||||
| modkey + c -> o | Launche obsidian |
|
|
||||||
| modkey + a -> j | Launche jetbrains-toolbox |
|
|
||||||
| modkey + a -> n | Launche NeoVim in the main terminal |
|
|
||||||
| modkey + a -> v | Launche Vim in the main terminal |
|
|
||||||
| modkey + a -> e | Launche emacs |
|
|
||||||
| modkey + p -> b | Launche the background manger (nitrogen by default) |
|
|
||||||
| modkey + p -> n | Lanuche the network manager (nm-connection-editor) |
|
|
||||||
| modkey + e | Launche rofi emoji selector |
|
|
||||||
| modkey + f | Toggle full screen mode |
|
|
||||||
| modkey + b | Toggle the status bar (hide/show) |
|
|
||||||
| modkey + j | Change the focus to privus window in the stack |
|
|
||||||
| modkey + k | Change the focus to the next window in the stack |
|
|
||||||
| modkey + i | Change the stack layout to virtecal |
|
|
||||||
| modkey + d | Change the stack layout to horizontal |
|
|
||||||
| modkey + h | Decrease the focus window size |
|
|
||||||
| modkey + l | Increase the focus window size |
|
|
||||||
| modkey + Tab | Toggle between the curent tag and the privus tag |
|
|
||||||
| modkey + shift + j | Move the focus window down in the stack |
|
|
||||||
| modkey + shift + k | Move the focus window up in the stack |
|
|
||||||
| modkey + q -> q | Quit from the focus window (kill it) |
|
|
||||||
| modkey + s -> t | Use the tile layout |
|
|
||||||
| modkey + s -> f | Use the float layout |
|
|
||||||
| modkey + s -> m | Use the monocle layout |
|
|
||||||
| modkey + s -> g | Use the grid layout |
|
|
||||||
| modkey + s -> r | Use the spial layout (part from fibonacci layouts) |
|
|
||||||
| modkey + s -> shift + r | Use the dwindle layout (part from fibonacci layouts) |
|
|
||||||
| modkey + s -> c | Use the centerd master layout |
|
|
||||||
| modkey + s -> shift + s | Use the centerd floating master layout |
|
|
||||||
| modkey + s -> space | Toggle between current layout and tile layout |
|
|
||||||
| modkey + shift + s | Toggle sticky mode |
|
|
||||||
| modkey + alt + f | Toggle floating window |
|
|
||||||
| modkey + m -> c | Launche the cmus player |
|
|
||||||
| modkey + m -> v | Launche vlc video player |
|
|
||||||
| modkey + m -> shift + v | Lanuche nvlc in the main terminal |
|
|
||||||
| modkey + 0 | View all tags |
|
|
||||||
| modkey + shift + 0 | Mirror the current tag in all tags |
|
|
||||||
| modkey + comma (,) | - |
|
|
||||||
| modkey + period (.) | - |
|
|
||||||
| modkey + shift + comma (,) | - |
|
|
||||||
| modkey + shift + period (.) | - |
|
|
||||||
| modkey + (1..9) | Navigate between tags |
|
|
||||||
| modkey + shift + (1..9) | Move the focus window to specific tag |
|
|
||||||
| modkey + control + (1..9) | - |
|
|
||||||
| modkey + shift + ctrl + (1..9) | Mirror the current tag in specific tag |
|
|
||||||
| superkey + space | Change the keyboard layout (ar, en) |
|
|
||||||
| PrtSc | Take a screenshot using default screenshot tool (spectacle) |
|
|
||||||
| modkey + shift + x | Lock the screen (using betterlockscreen) |
|
|
||||||
| modkey + shift + alt + q | Kill dwm |
|
|
||||||
|
|
||||||
> modkey = win key or super key
|
|
||||||
|
|
||||||
### Dependencies (apps)
|
|
||||||
- `google-chrome-stable` the main web browser
|
|
||||||
- `alacritty` the main terminal
|
|
||||||
- `spectacle` the main screenshot tool
|
|
||||||
- `pcmanfm` the GUI file manger
|
|
||||||
- `rofi`
|
|
||||||
- `dmenu`
|
|
||||||
- `libxinerama-dev`\*\*
|
|
||||||
- `tmux`\*
|
|
||||||
- `tor-browser`
|
|
||||||
- `discord`
|
|
||||||
- `libxft-bgra` for color emojies support
|
- `libxft-bgra` for color emojies support
|
||||||
- `jetbrains-toolbox`
|
- `archy-slstatus` the status bar
|
||||||
- `nvim`\*
|
|
||||||
- `vim`\*
|
|
||||||
- `xbacklight` for control in the screen brightness
|
|
||||||
- `pamixer` for control in the audio level
|
|
||||||
- `playerctl` for control in the media
|
|
||||||
- `pactl` for control in the mic
|
|
||||||
- `betterlockscreen` for lock screen
|
|
||||||
- `setxkbmap` for switch between keyboard layouts, like (ar, en)
|
|
||||||
- `slstatus` the status bar
|
|
||||||
- `network-manager-applet`
|
|
||||||
- `picom` compositor , for transparency
|
|
||||||
- `nitrogen` for set the wallpaper
|
|
||||||
- `copyq` clipboard manager
|
|
||||||
- `obsidian`
|
|
||||||
|
|
||||||
> \*\*: build dependencie.
|
|
||||||
|
|
||||||
### Install
|
|
||||||
- Manual:
|
|
||||||
1. Run this command to install all avilable dependencies in standerd arch repostory
|
|
||||||
```bash
|
|
||||||
sudo pacman -S google-chrome libxft-bgra rofi dmenu tmux tor-browser discord neovim jetbrains-toolbox vim pamixer playerctl betterlockscreen pcmanfm spectacle alacritty picom nitrogen libxinerama network-manager-applet copyq obsidian
|
|
||||||
```
|
|
||||||
2. Install yay if you not installed it.
|
|
||||||
3. Run this command to install all avilable dependencies in the AUR repostory `yay -S xkblayout`
|
|
||||||
4. Clone this repostory `git clone https://github.com/anas-elgarhy/dwm-anas.git`
|
|
||||||
5. Go to the source directory `cd dwm-anas/src`
|
|
||||||
6. Build and install `sudo make install clean`
|
|
||||||
7. Enjoy 😉
|
|
||||||
|
|
||||||
|
|
||||||
### Available in
|
|
||||||
|
|
||||||
[![GitHub](https://img.shields.io/badge/GitHub-Main%20repo-brightgreen?style=for-the-badge&logo=GitHub)](https://github.com/anas-elgarhy/dwm-anas)
|
|
||||||
[![GitLab](https://img.shields.io/badge/GitLab-Mirror%20repo-brightgreen?style=for-the-badge&logo=GitLab)](https://gitlab.com/anas-elgarhy/dwm-anas)
|
|
||||||
[![BitBucket](https://img.shields.io/badge/BitBucket-Mirror%20repo-brightgreen?style=for-the-badge&logo=BitBucket)](https://bitbucket.org/anas_elgarhy/dwm-anas)
|
|
||||||
[![Codeberg](https://img.shields.io/badge/Codeberg-Mirror%20repo-brightgreen?style=for-the-badge&logo=Codeberg)](https://codeberg.org/anas-elgarhy/dwm-anas)
|
|
||||||
|
|
||||||
|
### Mirrors
|
||||||
|
* [GitHub](https://github.com/archy-linux/archy-dwm) - The upstream repository
|
||||||
|
* [GitLab](https://gitlab.com/archy-linux/archy-dwm) - [![Mirror the repo to gitlab](https://github.com/archy-linux/archy-dwm/actions/workflows/gitlab-mirror.yml/badge.svg)](https://github.com/archy-linux/archy-dwm/actions/workflows/gitlab-mirror.yml)
|
||||||
|
* [NotABug](https://notabug.org/archy-linux/archy-dwm) - Not instant updates
|
||||||
|
* [Codeberg](https://codeberg.org/archy-linux/archy-dwm) - [![Mirror the repo to codeberg](https://github.com/archy-linux/archy-dwm/actions/workflows/codeberg-mirror.yml/badge.svg)](https://github.com/archy-linux/archy-dwm/actions/workflows/codeberg-mirror.yml)
|
||||||
|
* [Gitea](https://gitea.com/archy-linux/archy-dwm) - [![Mirror the repo to Gitea](https://github.com/archy-linux/archy-dwm/actions/workflows/gitea-mirror.yml/badge.svg)](https://github.com/archy-linux/archy-dwm/actions/workflows/gitea-mirror.yml)
|
||||||
|
* [Gitdab](https://gitdab.com/archy-linux/archy-dwm) - [![Mirror the repo to Gitdab](https://github.com/archy-linux/archy-dwm/actions/workflows/gitdab-mirror.yml/badge.svg)](https://github.com/archy-linux/archy-dwm/actions/workflows/gitdab-mirror.yml)
|
||||||
|
* [Pagure](https://pagure.io/archy-dwm) - [![Mirror the repo to pagure](https://github.com/archy-linux/archy-dwm/actions/workflows/pagure-mirror.yml/badge.svg)](https://github.com/archy-linux/archy-dwm/actions/workflows/pagure-mirror.yml)
|
||||||
|
* [Bitbucket](https://bitbucket.org/anas_elgarhy/archy-dwm) - [![Mirror the repo to bitbucket](https://github.com/archy-linux/archy-dwm/actions/workflows/bitbucket-mirror.yml/badge.svg)](https://github.com/archy-linux/archy-dwm/actions/workflows/bitbucket-mirror.yml)
|
||||||
|
* [disroot](https://git.disroot.org/archy-linux/archy-dwm) - [![Mirror the repo to disroot](https://github.com/archy-linux/archy-dwm/actions/workflows/disroot-mirror.yml/badge.svg)](https://github.com/archy-linux/archy-dwm/actions/workflows/disroot-mirror.yml)
|
||||||
|
|
||||||
|
### References:
|
||||||
|
- [XF86keysym](https://cgit.freedesktop.org/xorg/proto/x11proto/tree/XF86keysym.h)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# dwm-anas version
|
# Archy DWM version
|
||||||
VERSION = 6.3-0.1.2
|
VERSION = 2.0.0
|
||||||
|
|
||||||
# Customize below to fit your system
|
# Customize below to fit your system
|
||||||
|
|
|
@ -1,562 +0,0 @@
|
||||||
diff --git a/src/config.def.h.rej b/src/config.def.h.rej
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..82ea963
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/src/config.def.h.rej
|
|
||||||
@@ -0,0 +1,13 @@
|
|
||||||
+--- config.def.h
|
|
||||||
++++ config.def.h
|
|
||||||
+@@ -5,6 +5,10 @@ static const unsigned int borderpx = 1; /* border pixel of windows */
|
|
||||||
+ static const unsigned int snap = 32; /* snap pixel */
|
|
||||||
+ static const int showbar = 1; /* 0 means no bar */
|
|
||||||
+ static const int topbar = 1; /* 0 means bottom bar */
|
|
||||||
++static const int usealtbar = 1; /* 1 means use non-dwm status bar */
|
|
||||||
++static const char *altbarclass = "Polybar"; /* Alternate bar class name */
|
|
||||||
++static const char *alttrayname = "tray"; /* Polybar tray instance name */
|
|
||||||
++static const char *altbarcmd = "$HOME/bar.sh"; /* Alternate bar launch command */
|
|
||||||
+ static const char *fonts[] = { "monospace:size=10" };
|
|
||||||
+ static const char dmenufont[] = "monospace:size=10";
|
|
||||||
+ static const char col_gray1[] = "#222222";
|
|
||||||
diff --git a/src/config.h b/src/config.h
|
|
||||||
index 1e3fec2..43aa1e2 100644
|
|
||||||
--- a/src/config.h
|
|
||||||
+++ b/src/config.h
|
|
||||||
@@ -17,6 +17,12 @@ static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display
|
|
||||||
static const int showsystray = 1; /* 0 means no systray */
|
|
||||||
static const int showbar = 1; /* 0 means no bar */
|
|
||||||
static const int topbar = 1; /* 0 means bottom bar */
|
|
||||||
+
|
|
||||||
+static const int usealtbar = 1; /* 1 means use non-dwm status bar */
|
|
||||||
+static const char *altbarclass = "Polybar"; /* Alternate bar class name */
|
|
||||||
+static const char *alttrayname = "tray"; /* Polybar tray instance name */
|
|
||||||
+static const char *altbarcmd = "$HOME/bar.sh"; /* Alternate bar launch command */
|
|
||||||
+
|
|
||||||
static const char *fonts[] = { "monospace:size=11", "Noto Color Emoji:size=11", "Nerd Font Mono:weight=bold:size=15:antialias=true:hinting=true" };
|
|
||||||
static const char dmenufont[] = "monospace:size=11";
|
|
||||||
|
|
||||||
@@ -24,8 +30,6 @@ static const char dmenufont[] = "monospace:size=11";
|
|
||||||
|
|
||||||
// Autostart programs
|
|
||||||
static const char *const autostart[] = {
|
|
||||||
- // Start my build of slstatus
|
|
||||||
- "slstatus", NULL,
|
|
||||||
// Keyboard layouts switch (requires setxkbmap)
|
|
||||||
"setxkbmap", "-model", "pc101", "-layout", "us,ar", "-variant", ",,", "-option", "grp:win_space_toggle", NULL,
|
|
||||||
// "xkbset", "exp", "=sticky", "-twokey", "-latchlock", NULL, // sticky keys
|
|
||||||
diff --git a/src/dwm.c b/src/dwm.c
|
|
||||||
index eb423c5..0499e58 100644
|
|
||||||
--- a/src/dwm.c
|
|
||||||
+++ b/src/dwm.c
|
|
||||||
@@ -47,8 +47,8 @@
|
|
||||||
/* macros */
|
|
||||||
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
|
|
||||||
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
|
|
||||||
-#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
|
|
||||||
- * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
|
|
||||||
+#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->mx+(m)->mw) - MAX((x),(m)->mx)) \
|
|
||||||
+ * MAX(0, MIN((y)+(h),(m)->my+(m)->mh) - MAX((y),(m)->my)))
|
|
||||||
#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]) || C->issticky)
|
|
||||||
#define LENGTH(X) (sizeof X / sizeof X[0])
|
|
||||||
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
|
||||||
@@ -137,7 +137,8 @@ struct Monitor {
|
|
||||||
float mfact;
|
|
||||||
int nmaster;
|
|
||||||
int num;
|
|
||||||
- int by; /* bar geometry */
|
|
||||||
+ int by, bh; /* bar geometry */
|
|
||||||
+ int tx, tw; /* bar tray geometry */
|
|
||||||
int mx, my, mw, mh; /* screen size */
|
|
||||||
int wx, wy, ww, wh; /* window area */
|
|
||||||
unsigned int seltags;
|
|
||||||
@@ -150,6 +151,7 @@ struct Monitor {
|
|
||||||
Client *stack;
|
|
||||||
Monitor *next;
|
|
||||||
Window barwin;
|
|
||||||
+ Window traywin;
|
|
||||||
const Layout *lt[2];
|
|
||||||
Pertag *pertag;
|
|
||||||
};
|
|
||||||
@@ -208,6 +210,8 @@ static void incnmaster(const Arg *arg);
|
|
||||||
static void keypress(XEvent *e);
|
|
||||||
static void killclient(const Arg *arg);
|
|
||||||
static void manage(Window w, XWindowAttributes *wa);
|
|
||||||
+static void managealtbar(Window win, XWindowAttributes *wa);
|
|
||||||
+static void managetray(Window win, XWindowAttributes *wa);
|
|
||||||
static void mappingnotify(XEvent *e);
|
|
||||||
static void maprequest(XEvent *e);
|
|
||||||
static void monocle(Monitor *m);
|
|
||||||
@@ -227,6 +231,7 @@ static void resizerequest(XEvent *e);
|
|
||||||
static void restack(Monitor *m);
|
|
||||||
static void run(void);
|
|
||||||
static void scan(void);
|
|
||||||
+static void scantray(void);
|
|
||||||
static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4);
|
|
||||||
static void sendmon(Client *c, Monitor *m);
|
|
||||||
static void setclientstate(Client *c, long state);
|
|
||||||
@@ -240,6 +245,7 @@ static void seturgent(Client *c, int urg);
|
|
||||||
static void showhide(Client *c);
|
|
||||||
static void sigchld(int unused);
|
|
||||||
static void spawn(const Arg *arg);
|
|
||||||
+static void spawnbar();
|
|
||||||
static Monitor *systraytomon(Monitor *m);
|
|
||||||
static void tag(const Arg *arg);
|
|
||||||
static void tagmon(const Arg *arg);
|
|
||||||
@@ -251,6 +257,8 @@ static void toggletag(const Arg *arg);
|
|
||||||
static void toggleview(const Arg *arg);
|
|
||||||
static void unfocus(Client *c, int setfocus);
|
|
||||||
static void unmanage(Client *c, int destroyed);
|
|
||||||
+static void unmanagealtbar(Window w);
|
|
||||||
+static void unmanagetray(Window w);
|
|
||||||
static void unmapnotify(XEvent *e);
|
|
||||||
static void updatebarpos(Monitor *m);
|
|
||||||
static void updatebars(void);
|
|
||||||
@@ -269,6 +277,7 @@ static void view(const Arg *arg);
|
|
||||||
static Client *wintoclient(Window w);
|
|
||||||
static Monitor *wintomon(Window w);
|
|
||||||
static Client *wintosystrayicon(Window w);
|
|
||||||
+static int wmclasscontains(Window win, const char *class, const char *name);
|
|
||||||
static int xerror(Display *dpy, XErrorEvent *ee);
|
|
||||||
static int xerrordummy(Display *dpy, XErrorEvent *ee);
|
|
||||||
static int xerrorstart(Display *dpy, XErrorEvent *ee);
|
|
||||||
@@ -595,8 +604,10 @@ cleanupmon(Monitor *mon)
|
|
||||||
for (m = mons; m && m->next != mon; m = m->next);
|
|
||||||
m->next = mon->next;
|
|
||||||
}
|
|
||||||
- XUnmapWindow(dpy, mon->barwin);
|
|
||||||
- XDestroyWindow(dpy, mon->barwin);
|
|
||||||
+ if (!usealtbar) {
|
|
||||||
+ XUnmapWindow(dpy, mon->barwin);
|
|
||||||
+ XDestroyWindow(dpy, mon->barwin);
|
|
||||||
+ }
|
|
||||||
free(mon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -779,6 +790,7 @@ createmon(void)
|
|
||||||
m->nmaster = nmaster;
|
|
||||||
m->showbar = showbar;
|
|
||||||
m->topbar = topbar;
|
|
||||||
+ m->bh = bh;
|
|
||||||
m->lt[0] = &layouts[0];
|
|
||||||
m->lt[1] = &layouts[1 % LENGTH(layouts)];
|
|
||||||
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
|
|
||||||
@@ -803,10 +815,15 @@ void
|
|
||||||
destroynotify(XEvent *e)
|
|
||||||
{
|
|
||||||
Client *c;
|
|
||||||
+ Monitor *m;
|
|
||||||
XDestroyWindowEvent *ev = &e->xdestroywindow;
|
|
||||||
|
|
||||||
if ((c = wintoclient(ev->window)))
|
|
||||||
unmanage(c, 1);
|
|
||||||
+ else if ((m = wintomon(ev->window)) && m->barwin == ev->window)
|
|
||||||
+ unmanagealtbar(ev->window);
|
|
||||||
+ else if (m->traywin == ev->window)
|
|
||||||
+ unmanagetray(ev->window);
|
|
||||||
else if ((c = wintosystrayicon(ev->window))) {
|
|
||||||
removesystrayicon(c);
|
|
||||||
resizebarwin(selmon);
|
|
||||||
@@ -855,6 +872,8 @@ dirtomon(int dir)
|
|
||||||
void
|
|
||||||
drawbar(Monitor *m)
|
|
||||||
{
|
|
||||||
+ if (usealtbar) return;
|
|
||||||
+
|
|
||||||
int x, w, tw = 0, stw = 0;
|
|
||||||
int boxs = drw->fonts->h / 9;
|
|
||||||
int boxw = drw->fonts->h / 6 + 2;
|
|
||||||
@@ -1325,6 +1344,8 @@ maprequest(XEvent *e)
|
|
||||||
return;
|
|
||||||
if (wa.override_redirect)
|
|
||||||
return;
|
|
||||||
+ if (wmclasscontains(ev->window, altbarclass, ""))
|
|
||||||
+ managealtbar(ev->window, &wa);
|
|
||||||
if (!wintoclient(ev->window))
|
|
||||||
manage(ev->window, &wa);
|
|
||||||
}
|
|
||||||
@@ -1525,7 +1546,7 @@ resizebarwin(Monitor *m) {
|
|
||||||
unsigned int w = m->ww;
|
|
||||||
if (showsystray && m == systraytomon(m) && !systrayonleft)
|
|
||||||
w -= getsystraywidth();
|
|
||||||
- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh);
|
|
||||||
+ XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, m->bh);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
@@ -1668,8 +1689,10 @@ scan(void)
|
|
||||||
for (i = 0; i < num; i++) {
|
|
||||||
if (!XGetWindowAttributes(dpy, wins[i], &wa)
|
|
||||||
|| wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
|
|
||||||
- continue;
|
|
||||||
- if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)
|
|
||||||
+ continue;
|
|
||||||
+ if (wmclasscontains(wins[i], altbarclass, ""))
|
|
||||||
+ managealtbar(wins[i], &wa);
|
|
||||||
+ else if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)
|
|
||||||
manage(wins[i], &wa);
|
|
||||||
}
|
|
||||||
for (i = 0; i < num; i++) { /* now the transients */
|
|
||||||
@@ -1684,6 +1707,28 @@ scan(void)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+scantray(void)
|
|
||||||
+{
|
|
||||||
+ unsigned int num;
|
|
||||||
+ Window d1, d2, *wins = NULL;
|
|
||||||
+ XWindowAttributes wa;
|
|
||||||
+
|
|
||||||
+ if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
|
|
||||||
+ for (unsigned int i = 0; i < num; i++) {
|
|
||||||
+ if (wmclasscontains(wins[i], altbarclass, alttrayname)) {
|
|
||||||
+ if (!XGetWindowAttributes(dpy, wins[i], &wa))
|
|
||||||
+ break;
|
|
||||||
+ managetray(wins[i], &wa);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (wins)
|
|
||||||
+ XFree(wins);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
void
|
|
||||||
sendmon(Client *c, Monitor *m)
|
|
||||||
{
|
|
||||||
@@ -1848,7 +1893,7 @@ setup(void)
|
|
||||||
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
|
|
||||||
die("no fonts could be loaded.");
|
|
||||||
lrpad = drw->fonts->h;
|
|
||||||
- bh = drw->fonts->h + 2;
|
|
||||||
+ bh = usealtbar ? 0 : drw->fonts->h + 2;
|
|
||||||
updategeom();
|
|
||||||
/* init atoms */
|
|
||||||
utf8string = XInternAtom(dpy, "UTF8_STRING", False);
|
|
||||||
@@ -1906,6 +1951,7 @@ setup(void)
|
|
||||||
XSelectInput(dpy, root, wa.event_mask);
|
|
||||||
grabkeys();
|
|
||||||
focus(NULL);
|
|
||||||
+ spawnbar();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1980,6 +2026,13 @@ spawn(const Arg *arg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+void
|
|
||||||
+spawnbar()
|
|
||||||
+{
|
|
||||||
+ if (*altbarcmd)
|
|
||||||
+ system(altbarcmd);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
void
|
|
||||||
tag(const Arg *arg)
|
|
||||||
{
|
|
||||||
@@ -2001,9 +2054,19 @@ tagmon(const Arg *arg)
|
|
||||||
void
|
|
||||||
togglebar(const Arg *arg)
|
|
||||||
{
|
|
||||||
+ /**
|
|
||||||
+ * Polybar tray does not raise maprequest event. It must be manually scanned
|
|
||||||
+ * for. Scanning it too early while the tray is being populated would give
|
|
||||||
+ * wrong dimensions.
|
|
||||||
+ */
|
|
||||||
+ if (!selmon->traywin)
|
|
||||||
+ scantray();
|
|
||||||
+
|
|
||||||
selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar;
|
|
||||||
updatebarpos(selmon);
|
|
||||||
resizebarwin(selmon);
|
|
||||||
+ //TODO: 2022-07-17 Test
|
|
||||||
+ XMoveResizeWindow(dpy, selmon->traywin, selmon->tx, selmon->by, selmon->tw, selmon->bh);
|
|
||||||
if (showsystray) {
|
|
||||||
XWindowChanges wc;
|
|
||||||
if (!selmon->showbar)
|
|
||||||
@@ -2018,6 +2081,38 @@ togglebar(const Arg *arg)
|
|
||||||
arrange(selmon);
|
|
||||||
}
|
|
||||||
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+unmanagealtbar(Window w)
|
|
||||||
+{
|
|
||||||
+ Monitor *m = wintomon(w);
|
|
||||||
+
|
|
||||||
+ if (!m)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ m->barwin = 0;
|
|
||||||
+ m->by = 0;
|
|
||||||
+ m->bh = 0;
|
|
||||||
+ updatebarpos(m);
|
|
||||||
+ arrange(m);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+unmanagetray(Window w)
|
|
||||||
+{
|
|
||||||
+ Monitor *m = wintomon(w);
|
|
||||||
+
|
|
||||||
+ if (!m)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ m->traywin = 0;
|
|
||||||
+ m->tx = 0;
|
|
||||||
+ m->tw = 0;
|
|
||||||
+ updatebarpos(m);
|
|
||||||
+ arrange(m);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
void
|
|
||||||
togglefloating(const Arg *arg)
|
|
||||||
{
|
|
||||||
@@ -2134,6 +2229,7 @@ void
|
|
||||||
unmapnotify(XEvent *e)
|
|
||||||
{
|
|
||||||
Client *c;
|
|
||||||
+ Monitor *m;
|
|
||||||
XUnmapEvent *ev = &e->xunmap;
|
|
||||||
|
|
||||||
if ((c = wintoclient(ev->window))) {
|
|
||||||
@@ -2141,7 +2237,10 @@ unmapnotify(XEvent *e)
|
|
||||||
setclientstate(c, WithdrawnState);
|
|
||||||
else
|
|
||||||
unmanage(c, 0);
|
|
||||||
- }
|
|
||||||
+ } else if ((m = wintomon(ev->window)) && m->barwin == ev->window)
|
|
||||||
+ unmanagealtbar(ev->window);
|
|
||||||
+ else if (m->traywin == ev->window)
|
|
||||||
+ unmanagetray(ev->window);
|
|
||||||
else if ((c = wintosystrayicon(ev->window))) {
|
|
||||||
/* KLUDGE! sometimes icons occasionally unmap their windows, but do
|
|
||||||
* _not_ destroy them. We map those windows back */
|
|
||||||
@@ -2153,6 +2252,8 @@ unmapnotify(XEvent *e)
|
|
||||||
void
|
|
||||||
updatebars(void)
|
|
||||||
{
|
|
||||||
+ if (usealtbar) return;
|
|
||||||
+
|
|
||||||
unsigned int w;
|
|
||||||
Monitor *m;
|
|
||||||
XSetWindowAttributes wa = {
|
|
||||||
@@ -2184,11 +2285,11 @@ updatebarpos(Monitor *m)
|
|
||||||
m->wy = m->my;
|
|
||||||
m->wh = m->mh;
|
|
||||||
if (m->showbar) {
|
|
||||||
- m->wh -= bh;
|
|
||||||
+ m->wh -= m->bh;
|
|
||||||
m->by = m->topbar ? m->wy : m->wy + m->wh;
|
|
||||||
- m->wy = m->topbar ? m->wy + bh : m->wy;
|
|
||||||
+ m->wy = m->topbar ? m->wy + m->bh : m->wy;
|
|
||||||
} else
|
|
||||||
- m->by = -bh;
|
|
||||||
+ m->by = -m->bh;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
@@ -2491,6 +2592,45 @@ updatewindowtype(Client *c)
|
|
||||||
c->isfloating = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+managealtbar(Window win, XWindowAttributes *wa)
|
|
||||||
+{
|
|
||||||
+ Monitor *m;
|
|
||||||
+ if (!(m = recttomon(wa->x, wa->y, wa->width, wa->height)))
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ m->barwin = win;
|
|
||||||
+ m->by = wa->y;
|
|
||||||
+ bh = m->bh = wa->height;
|
|
||||||
+ updatebarpos(m);
|
|
||||||
+ arrange(m);
|
|
||||||
+ XSelectInput(dpy, win, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
|
|
||||||
+ XMoveResizeWindow(dpy, win, wa->x, wa->y, wa->width, wa->height);
|
|
||||||
+ XMapWindow(dpy, win);
|
|
||||||
+ XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
|
|
||||||
+ (unsigned char *) &win, 1);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+managetray(Window win, XWindowAttributes *wa)
|
|
||||||
+{
|
|
||||||
+ Monitor *m;
|
|
||||||
+ if (!(m = recttomon(wa->x, wa->y, wa->width, wa->height)))
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ m->traywin = win;
|
|
||||||
+ m->tx = wa->x;
|
|
||||||
+ m->tw = wa->width;
|
|
||||||
+ updatebarpos(m);
|
|
||||||
+ arrange(m);
|
|
||||||
+ XSelectInput(dpy, win, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
|
|
||||||
+ XMoveResizeWindow(dpy, win, wa->x, wa->y, wa->width, wa->height);
|
|
||||||
+ XMapWindow(dpy, win);
|
|
||||||
+ XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
|
|
||||||
+ (unsigned char *) &win, 1);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
void
|
|
||||||
updatewmhints(Client *c)
|
|
||||||
{
|
|
||||||
@@ -2581,13 +2721,36 @@ wintomon(Window w)
|
|
||||||
if (w == root && getrootptr(&x, &y))
|
|
||||||
return recttomon(x, y, 1, 1);
|
|
||||||
for (m = mons; m; m = m->next)
|
|
||||||
- if (w == m->barwin)
|
|
||||||
+ if (w == m->barwin || w == m->traywin)
|
|
||||||
return m;
|
|
||||||
if ((c = wintoclient(w)))
|
|
||||||
return c->mon;
|
|
||||||
return selmon;
|
|
||||||
}
|
|
||||||
|
|
||||||
+
|
|
||||||
+int
|
|
||||||
+wmclasscontains(Window win, const char *class, const char *name)
|
|
||||||
+{
|
|
||||||
+ XClassHint ch = { NULL, NULL };
|
|
||||||
+ int res = 1;
|
|
||||||
+
|
|
||||||
+ if (XGetClassHint(dpy, win, &ch)) {
|
|
||||||
+ if (ch.res_name && strstr(ch.res_name, name) == NULL)
|
|
||||||
+ res = 0;
|
|
||||||
+ if (ch.res_class && strstr(ch.res_class, class) == NULL)
|
|
||||||
+ res = 0;
|
|
||||||
+ } else
|
|
||||||
+ res = 0;
|
|
||||||
+
|
|
||||||
+ if (ch.res_class)
|
|
||||||
+ XFree(ch.res_class);
|
|
||||||
+ if (ch.res_name)
|
|
||||||
+ XFree(ch.res_name);
|
|
||||||
+
|
|
||||||
+ return res;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/* There's no way to check accesses to destroyed windows, thus those cases are
|
|
||||||
* ignored (especially on UnmapNotify's). Other types of errors call Xlibs
|
|
||||||
* default error handler, which may call exit. */
|
|
||||||
diff --git a/src/dwm.c.rej b/src/dwm.c.rej
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..7e375c6
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/src/dwm.c.rej
|
|
||||||
@@ -0,0 +1,112 @@
|
|
||||||
+--- dwm.c
|
|
||||||
++++ dwm.c
|
|
||||||
+@@ -47,8 +47,8 @@
|
|
||||||
+ /* macros */
|
|
||||||
+ #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
|
|
||||||
+ #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
|
|
||||||
+-#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
|
|
||||||
+- * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
|
|
||||||
++#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->mx+(m)->mw) - MAX((x),(m)->mx)) \
|
|
||||||
++ * MAX(0, MIN((y)+(h),(m)->my+(m)->mh) - MAX((y),(m)->my)))
|
|
||||||
+ #define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
|
|
||||||
+ #define LENGTH(X) (sizeof X / sizeof X[0])
|
|
||||||
+ #define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
|
||||||
+@@ -199,6 +203,7 @@ static void resizemouse(const Arg *arg);
|
|
||||||
+ static void restack(Monitor *m);
|
|
||||||
+ static void run(void);
|
|
||||||
+ static void scan(void);
|
|
||||||
++static void scantray(void);
|
|
||||||
+ static int sendevent(Client *c, Atom proto);
|
|
||||||
+ static void sendmon(Client *c, Monitor *m);
|
|
||||||
+ static void setclientstate(Client *c, long state);
|
|
||||||
+@@ -211,6 +216,7 @@ static void seturgent(Client *c, int urg);
|
|
||||||
+ static void showhide(Client *c);
|
|
||||||
+ static void sigchld(int unused);
|
|
||||||
+ static void spawn(const Arg *arg);
|
|
||||||
++static void spawnbar();
|
|
||||||
+ static void tag(const Arg *arg);
|
|
||||||
+ static void tagmon(const Arg *arg);
|
|
||||||
+ static void tile(Monitor *);
|
|
||||||
+@@ -236,6 +244,7 @@ static void updatewmhints(Client *c);
|
|
||||||
+ static void view(const Arg *arg);
|
|
||||||
+ static Client *wintoclient(Window w);
|
|
||||||
+ static Monitor *wintomon(Window w);
|
|
||||||
++static int wmclasscontains(Window win, const char *class, const char *name);
|
|
||||||
+ static int xerror(Display *dpy, XErrorEvent *ee);
|
|
||||||
+ static int xerrordummy(Display *dpy, XErrorEvent *ee);
|
|
||||||
+ static int xerrorstart(Display *dpy, XErrorEvent *ee);
|
|
||||||
+@@ -576,7 +587,7 @@ configurenotify(XEvent *e)
|
|
||||||
+ for (c = m->clients; c; c = c->next)
|
|
||||||
+ if (c->isfullscreen)
|
|
||||||
+ resizeclient(c, m->mx, m->my, m->mw, m->mh);
|
|
||||||
+- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
|
|
||||||
++ XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, m->bh);
|
|
||||||
+ }
|
|
||||||
+ focus(NULL);
|
|
||||||
+ arrange(NULL);
|
|
||||||
+@@ -658,10 +670,15 @@ void
|
|
||||||
+ destroynotify(XEvent *e)
|
|
||||||
+ {
|
|
||||||
+ Client *c;
|
|
||||||
++ Monitor *m;
|
|
||||||
+ XDestroyWindowEvent *ev = &e->xdestroywindow;
|
|
||||||
+
|
|
||||||
+ if ((c = wintoclient(ev->window)))
|
|
||||||
+ unmanage(c, 1);
|
|
||||||
++ else if ((m = wintomon(ev->window)) && m->barwin == ev->window)
|
|
||||||
++ unmanagealtbar(ev->window);
|
|
||||||
++ else if (m->traywin == ev->window)
|
|
||||||
++ unmanagetray(ev->window);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ void
|
|
||||||
+@@ -705,6 +722,9 @@ dirtomon(int dir)
|
|
||||||
+ void
|
|
||||||
+ drawbar(Monitor *m)
|
|
||||||
+ {
|
|
||||||
++ if (usealtbar)
|
|
||||||
++ return;
|
|
||||||
++
|
|
||||||
+ int x, w, tw = 0;
|
|
||||||
+ int boxs = drw->fonts->h / 9;
|
|
||||||
+ int boxw = drw->fonts->h / 6 + 2;
|
|
||||||
+@@ -1785,9 +1879,18 @@ tile(Monitor *m)
|
|
||||||
+ void
|
|
||||||
+ togglebar(const Arg *arg)
|
|
||||||
+ {
|
|
||||||
++ /**
|
|
||||||
++ * Polybar tray does not raise maprequest event. It must be manually scanned
|
|
||||||
++ * for. Scanning it too early while the tray is being populated would give
|
|
||||||
++ * wrong dimensions.
|
|
||||||
++ */
|
|
||||||
++ if (!selmon->traywin)
|
|
||||||
++ scantray();
|
|
||||||
++
|
|
||||||
+ selmon->showbar = !selmon->showbar;
|
|
||||||
+ updatebarpos(selmon);
|
|
||||||
+- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
|
|
||||||
++ XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, selmon->bh);
|
|
||||||
++ XMoveResizeWindow(dpy, selmon->traywin, selmon->tx, selmon->by, selmon->tw, selmon->bh);
|
|
||||||
+ arrange(selmon);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+@@ -1912,12 +2046,18 @@ unmapnotify(XEvent *e)
|
|
||||||
+ setclientstate(c, WithdrawnState);
|
|
||||||
+ else
|
|
||||||
+ unmanage(c, 0);
|
|
||||||
+- }
|
|
||||||
++ } else if ((m = wintomon(ev->window)) && m->barwin == ev->window)
|
|
||||||
++ unmanagealtbar(ev->window);
|
|
||||||
++ else if (m->traywin == ev->window)
|
|
||||||
++ unmanagetray(ev->window);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ void
|
|
||||||
+ updatebars(void)
|
|
||||||
+ {
|
|
||||||
++ if (usealtbar)
|
|
||||||
++ return;
|
|
||||||
++
|
|
||||||
+ Monitor *m;
|
|
||||||
+ XSetWindowAttributes wa = {
|
|
||||||
+ .override_redirect = True,
|
|
|
@ -1,12 +0,0 @@
|
||||||
diff -up dwm/dwm.c dwmmod/dwm.c
|
|
||||||
--- dwm/dwm.c 2020-06-25 00:21:30.383692180 -0300
|
|
||||||
+++ dwmmod/dwm.c 2020-06-25 00:20:35.643692330 -0300
|
|
||||||
@@ -1057,6 +1057,8 @@ manage(Window w, XWindowAttributes *wa)
|
|
||||||
updatewindowtype(c);
|
|
||||||
updatesizehints(c);
|
|
||||||
updatewmhints(c);
|
|
||||||
+ c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2;
|
|
||||||
+ c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2;
|
|
||||||
XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
|
|
||||||
grabbuttons(c, 0);
|
|
||||||
if (!c->isfloating)
|
|
|
@ -1,142 +0,0 @@
|
||||||
diff --git a/config.def.h b/config.def.h
|
|
||||||
index fd77a07..f025619 100644
|
|
||||||
--- a/config.def.h
|
|
||||||
+++ b/config.def.h
|
|
||||||
@@ -41,6 +41,8 @@ static const Layout layouts[] = {
|
|
||||||
{ "[]=", tile }, /* first entry is default */
|
|
||||||
{ "><>", NULL }, /* no layout function means floating behavior */
|
|
||||||
{ "[M]", monocle },
|
|
||||||
+ { "|M|", centeredmaster },
|
|
||||||
+ { ">M>", centeredfloatingmaster },
|
|
||||||
};
|
|
||||||
|
|
||||||
/* key definitions */
|
|
||||||
@@ -76,6 +78,8 @@ static Key keys[] = {
|
|
||||||
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
|
||||||
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
|
|
||||||
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
|
|
||||||
+ { MODKEY, XK_u, setlayout, {.v = &layouts[3]} },
|
|
||||||
+ { MODKEY, XK_o, setlayout, {.v = &layouts[4]} },
|
|
||||||
{ MODKEY, XK_space, setlayout, {0} },
|
|
||||||
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
|
||||||
{ MODKEY, XK_0, view, {.ui = ~0 } },
|
|
||||||
diff --git a/dwm.c b/dwm.c
|
|
||||||
index b2bc9bd..9ecabae 100644
|
|
||||||
--- a/dwm.c
|
|
||||||
+++ b/dwm.c
|
|
||||||
@@ -234,6 +234,8 @@ static int xerror(Display *dpy, XErrorEvent *ee);
|
|
||||||
static int xerrordummy(Display *dpy, XErrorEvent *ee);
|
|
||||||
static int xerrorstart(Display *dpy, XErrorEvent *ee);
|
|
||||||
static void zoom(const Arg *arg);
|
|
||||||
+static void centeredmaster(Monitor *m);
|
|
||||||
+static void centeredfloatingmaster(Monitor *m);
|
|
||||||
|
|
||||||
/* variables */
|
|
||||||
static const char broken[] = "broken";
|
|
||||||
@@ -2138,3 +2140,106 @@ main(int argc, char *argv[])
|
|
||||||
XCloseDisplay(dpy);
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+centeredmaster(Monitor *m)
|
|
||||||
+{
|
|
||||||
+ unsigned int i, n, h, mw, mx, my, oty, ety, tw;
|
|
||||||
+ Client *c;
|
|
||||||
+
|
|
||||||
+ /* count number of clients in the selected monitor */
|
|
||||||
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
|
|
||||||
+ if (n == 0)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ /* initialize areas */
|
|
||||||
+ mw = m->ww;
|
|
||||||
+ mx = 0;
|
|
||||||
+ my = 0;
|
|
||||||
+ tw = mw;
|
|
||||||
+
|
|
||||||
+ if (n > m->nmaster) {
|
|
||||||
+ /* go mfact box in the center if more than nmaster clients */
|
|
||||||
+ mw = m->nmaster ? m->ww * m->mfact : 0;
|
|
||||||
+ tw = m->ww - mw;
|
|
||||||
+
|
|
||||||
+ if (n - m->nmaster > 1) {
|
|
||||||
+ /* only one client */
|
|
||||||
+ mx = (m->ww - mw) / 2;
|
|
||||||
+ tw = (m->ww - mw) / 2;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ oty = 0;
|
|
||||||
+ ety = 0;
|
|
||||||
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
|
||||||
+ if (i < m->nmaster) {
|
|
||||||
+ /* nmaster clients are stacked vertically, in the center
|
|
||||||
+ * of the screen */
|
|
||||||
+ h = (m->wh - my) / (MIN(n, m->nmaster) - i);
|
|
||||||
+ resize(c, m->wx + mx, m->wy + my, mw - (2*c->bw),
|
|
||||||
+ h - (2*c->bw), 0);
|
|
||||||
+ my += HEIGHT(c);
|
|
||||||
+ } else {
|
|
||||||
+ /* stack clients are stacked vertically */
|
|
||||||
+ if ((i - m->nmaster) % 2 ) {
|
|
||||||
+ h = (m->wh - ety) / ( (1 + n - i) / 2);
|
|
||||||
+ resize(c, m->wx, m->wy + ety, tw - (2*c->bw),
|
|
||||||
+ h - (2*c->bw), 0);
|
|
||||||
+ ety += HEIGHT(c);
|
|
||||||
+ } else {
|
|
||||||
+ h = (m->wh - oty) / ((1 + n - i) / 2);
|
|
||||||
+ resize(c, m->wx + mx + mw, m->wy + oty,
|
|
||||||
+ tw - (2*c->bw), h - (2*c->bw), 0);
|
|
||||||
+ oty += HEIGHT(c);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+centeredfloatingmaster(Monitor *m)
|
|
||||||
+{
|
|
||||||
+ unsigned int i, n, w, mh, mw, mx, mxo, my, myo, tx;
|
|
||||||
+ Client *c;
|
|
||||||
+
|
|
||||||
+ /* count number of clients in the selected monitor */
|
|
||||||
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
|
|
||||||
+ if (n == 0)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ /* initialize nmaster area */
|
|
||||||
+ if (n > m->nmaster) {
|
|
||||||
+ /* go mfact box in the center if more than nmaster clients */
|
|
||||||
+ if (m->ww > m->wh) {
|
|
||||||
+ mw = m->nmaster ? m->ww * m->mfact : 0;
|
|
||||||
+ mh = m->nmaster ? m->wh * 0.9 : 0;
|
|
||||||
+ } else {
|
|
||||||
+ mh = m->nmaster ? m->wh * m->mfact : 0;
|
|
||||||
+ mw = m->nmaster ? m->ww * 0.9 : 0;
|
|
||||||
+ }
|
|
||||||
+ mx = mxo = (m->ww - mw) / 2;
|
|
||||||
+ my = myo = (m->wh - mh) / 2;
|
|
||||||
+ } else {
|
|
||||||
+ /* go fullscreen if all clients are in the master area */
|
|
||||||
+ mh = m->wh;
|
|
||||||
+ mw = m->ww;
|
|
||||||
+ mx = mxo = 0;
|
|
||||||
+ my = myo = 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ for(i = tx = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
|
||||||
+ if (i < m->nmaster) {
|
|
||||||
+ /* nmaster clients are stacked horizontally, in the center
|
|
||||||
+ * of the screen */
|
|
||||||
+ w = (mw + mxo - mx) / (MIN(n, m->nmaster) - i);
|
|
||||||
+ resize(c, m->wx + mx, m->wy + my, w - (2*c->bw),
|
|
||||||
+ mh - (2*c->bw), 0);
|
|
||||||
+ mx += WIDTH(c);
|
|
||||||
+ } else {
|
|
||||||
+ /* stack clients are stacked horizontally */
|
|
||||||
+ w = (m->ww - tx) / (n - i);
|
|
||||||
+ resize(c, m->wx + tx, m->wy, w - (2*c->bw),
|
|
||||||
+ m->wh - (2*c->bw), 0);
|
|
||||||
+ tx += WIDTH(c);
|
|
||||||
+ }
|
|
||||||
+}
|
|
|
@ -1,116 +0,0 @@
|
||||||
diff --git a/config.def.h b/config.def.h
|
|
||||||
index 1c0b587..ed056a4 100644
|
|
||||||
--- a/config.def.h
|
|
||||||
+++ b/config.def.h
|
|
||||||
@@ -18,6 +18,11 @@ static const char *colors[][3] = {
|
|
||||||
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
|
|
||||||
};
|
|
||||||
|
|
||||||
+static const char *const autostart[] = {
|
|
||||||
+ "st", NULL,
|
|
||||||
+ NULL /* terminate */
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
/* tagging */
|
|
||||||
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
|
|
||||||
|
|
||||||
diff --git a/dwm.c b/dwm.c
|
|
||||||
index 9fd0286..1facd56 100644
|
|
||||||
--- a/dwm.c
|
|
||||||
+++ b/dwm.c
|
|
||||||
@@ -234,6 +234,7 @@ static int xerror(Display *dpy, XErrorEvent *ee);
|
|
||||||
static int xerrordummy(Display *dpy, XErrorEvent *ee);
|
|
||||||
static int xerrorstart(Display *dpy, XErrorEvent *ee);
|
|
||||||
static void zoom(const Arg *arg);
|
|
||||||
+static void autostart_exec(void);
|
|
||||||
|
|
||||||
/* variables */
|
|
||||||
static const char broken[] = "broken";
|
|
||||||
@@ -275,6 +276,34 @@ static Window root, wmcheckwin;
|
|
||||||
/* compile-time check if all tags fit into an unsigned int bit array. */
|
|
||||||
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
|
|
||||||
|
|
||||||
+/* dwm will keep pid's of processes from autostart array and kill them at quit */
|
|
||||||
+static pid_t *autostart_pids;
|
|
||||||
+static size_t autostart_len;
|
|
||||||
+
|
|
||||||
+/* execute command from autostart array */
|
|
||||||
+static void
|
|
||||||
+autostart_exec() {
|
|
||||||
+ const char *const *p;
|
|
||||||
+ size_t i = 0;
|
|
||||||
+
|
|
||||||
+ /* count entries */
|
|
||||||
+ for (p = autostart; *p; autostart_len++, p++)
|
|
||||||
+ while (*++p);
|
|
||||||
+
|
|
||||||
+ autostart_pids = malloc(autostart_len * sizeof(pid_t));
|
|
||||||
+ for (p = autostart; *p; i++, p++) {
|
|
||||||
+ if ((autostart_pids[i] = fork()) == 0) {
|
|
||||||
+ setsid();
|
|
||||||
+ execvp(*p, (char *const *)p);
|
|
||||||
+ fprintf(stderr, "dwm: execvp %s\n", *p);
|
|
||||||
+ perror(" failed");
|
|
||||||
+ _exit(EXIT_FAILURE);
|
|
||||||
+ }
|
|
||||||
+ /* skip arguments */
|
|
||||||
+ while (*++p);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/* function implementations */
|
|
||||||
void
|
|
||||||
applyrules(Client *c)
|
|
||||||
@@ -1249,6 +1278,16 @@ propertynotify(XEvent *e)
|
|
||||||
void
|
|
||||||
quit(const Arg *arg)
|
|
||||||
{
|
|
||||||
+ size_t i;
|
|
||||||
+
|
|
||||||
+ /* kill child processes */
|
|
||||||
+ for (i = 0; i < autostart_len; i++) {
|
|
||||||
+ if (0 < autostart_pids[i]) {
|
|
||||||
+ kill(autostart_pids[i], SIGTERM);
|
|
||||||
+ waitpid(autostart_pids[i], NULL, 0);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
running = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1632,9 +1671,25 @@ showhide(Client *c)
|
|
||||||
void
|
|
||||||
sigchld(int unused)
|
|
||||||
{
|
|
||||||
+ pid_t pid;
|
|
||||||
+
|
|
||||||
if (signal(SIGCHLD, sigchld) == SIG_ERR)
|
|
||||||
die("can't install SIGCHLD handler:");
|
|
||||||
- while (0 < waitpid(-1, NULL, WNOHANG));
|
|
||||||
+ while (0 < (pid = waitpid(-1, NULL, WNOHANG))) {
|
|
||||||
+ pid_t *p, *lim;
|
|
||||||
+
|
|
||||||
+ if (!(p = autostart_pids))
|
|
||||||
+ continue;
|
|
||||||
+ lim = &p[autostart_len];
|
|
||||||
+
|
|
||||||
+ for (; p < lim; p++) {
|
|
||||||
+ if (*p == pid) {
|
|
||||||
+ *p = -1;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
@@ -2139,6 +2194,7 @@ main(int argc, char *argv[])
|
|
||||||
if (!(dpy = XOpenDisplay(NULL)))
|
|
||||||
die("dwm: cannot open display");
|
|
||||||
checkotherwm();
|
|
||||||
+ autostart_exec();
|
|
||||||
setup();
|
|
||||||
#ifdef __OpenBSD__
|
|
||||||
if (pledge("stdio rpath proc exec", NULL) == -1)
|
|
||||||
|
|
|
@ -1,114 +0,0 @@
|
||||||
From ec9f55b6005cfa3b025b3d700c61af3ce539d057 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Niki Yoshiuchi <nyoshiuchi@gmail.com>
|
|
||||||
Date: Sat, 18 Apr 2020 09:55:26 -0700
|
|
||||||
Subject: [PATCH] Adding the fibonacci layout patch
|
|
||||||
|
|
||||||
---
|
|
||||||
config.def.h | 5 ++++
|
|
||||||
fibonacci.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
2 files changed, 71 insertions(+)
|
|
||||||
create mode 100644 fibonacci.c
|
|
||||||
|
|
||||||
diff --git a/config.def.h b/config.def.h
|
|
||||||
index 1c0b587..5708487 100644
|
|
||||||
--- a/config.def.h
|
|
||||||
+++ b/config.def.h
|
|
||||||
@@ -36,11 +36,14 @@ static const float mfact = 0.55; /* factor of master area size [0.05..0.95]
|
|
||||||
static const int nmaster = 1; /* number of clients in master area */
|
|
||||||
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
|
|
||||||
|
|
||||||
+#include "fibonacci.c"
|
|
||||||
static const Layout layouts[] = {
|
|
||||||
/* symbol arrange function */
|
|
||||||
{ "[]=", tile }, /* first entry is default */
|
|
||||||
{ "><>", NULL }, /* no layout function means floating behavior */
|
|
||||||
{ "[M]", monocle },
|
|
||||||
+ { "[@]", spiral },
|
|
||||||
+ { "[\\]", dwindle },
|
|
||||||
};
|
|
||||||
|
|
||||||
/* key definitions */
|
|
||||||
@@ -76,6 +79,8 @@ static Key keys[] = {
|
|
||||||
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
|
||||||
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
|
|
||||||
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
|
|
||||||
+ { MODKEY, XK_r, setlayout, {.v = &layouts[3]} },
|
|
||||||
+ { MODKEY|ShiftMask, XK_r, setlayout, {.v = &layouts[4]} },
|
|
||||||
{ MODKEY, XK_space, setlayout, {0} },
|
|
||||||
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
|
||||||
{ MODKEY, XK_0, view, {.ui = ~0 } },
|
|
||||||
diff --git a/fibonacci.c b/fibonacci.c
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..fce0a57
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/fibonacci.c
|
|
||||||
@@ -0,0 +1,66 @@
|
|
||||||
+void
|
|
||||||
+fibonacci(Monitor *mon, int s) {
|
|
||||||
+ unsigned int i, n, nx, ny, nw, nh;
|
|
||||||
+ Client *c;
|
|
||||||
+
|
|
||||||
+ for(n = 0, c = nexttiled(mon->clients); c; c = nexttiled(c->next), n++);
|
|
||||||
+ if(n == 0)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ nx = mon->wx;
|
|
||||||
+ ny = 0;
|
|
||||||
+ nw = mon->ww;
|
|
||||||
+ nh = mon->wh;
|
|
||||||
+
|
|
||||||
+ for(i = 0, c = nexttiled(mon->clients); c; c = nexttiled(c->next)) {
|
|
||||||
+ if((i % 2 && nh / 2 > 2 * c->bw)
|
|
||||||
+ || (!(i % 2) && nw / 2 > 2 * c->bw)) {
|
|
||||||
+ if(i < n - 1) {
|
|
||||||
+ if(i % 2)
|
|
||||||
+ nh /= 2;
|
|
||||||
+ else
|
|
||||||
+ nw /= 2;
|
|
||||||
+ if((i % 4) == 2 && !s)
|
|
||||||
+ nx += nw;
|
|
||||||
+ else if((i % 4) == 3 && !s)
|
|
||||||
+ ny += nh;
|
|
||||||
+ }
|
|
||||||
+ if((i % 4) == 0) {
|
|
||||||
+ if(s)
|
|
||||||
+ ny += nh;
|
|
||||||
+ else
|
|
||||||
+ ny -= nh;
|
|
||||||
+ }
|
|
||||||
+ else if((i % 4) == 1)
|
|
||||||
+ nx += nw;
|
|
||||||
+ else if((i % 4) == 2)
|
|
||||||
+ ny += nh;
|
|
||||||
+ else if((i % 4) == 3) {
|
|
||||||
+ if(s)
|
|
||||||
+ nx += nw;
|
|
||||||
+ else
|
|
||||||
+ nx -= nw;
|
|
||||||
+ }
|
|
||||||
+ if(i == 0)
|
|
||||||
+ {
|
|
||||||
+ if(n != 1)
|
|
||||||
+ nw = mon->ww * mon->mfact;
|
|
||||||
+ ny = mon->wy;
|
|
||||||
+ }
|
|
||||||
+ else if(i == 1)
|
|
||||||
+ nw = mon->ww - nw;
|
|
||||||
+ i++;
|
|
||||||
+ }
|
|
||||||
+ resize(c, nx, ny, nw - 2 * c->bw, nh - 2 * c->bw, False);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+dwindle(Monitor *mon) {
|
|
||||||
+ fibonacci(mon, 1);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+spiral(Monitor *mon) {
|
|
||||||
+ fibonacci(mon, 0);
|
|
||||||
+}
|
|
||||||
--
|
|
||||||
2.20.1
|
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
From 54719285bd1a984e2efce6e8a8eab184fec11abf Mon Sep 17 00:00:00 2001
|
|
||||||
From: Sermak <sermak@jarvis.com>
|
|
||||||
Date: Mon, 8 Jul 2019 01:06:44 +0200
|
|
||||||
Subject: [PATCH] Simulate toggleable fullscreen mode
|
|
||||||
|
|
||||||
---
|
|
||||||
config.def.h | 1 +
|
|
||||||
dwm.c | 14 ++++++++++++++
|
|
||||||
2 files changed, 15 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/config.def.h b/config.def.h
|
|
||||||
index 1c0b587..f774cc5 100644
|
|
||||||
--- a/config.def.h
|
|
||||||
+++ b/config.def.h
|
|
||||||
@@ -76,6 +76,7 @@ static Key keys[] = {
|
|
||||||
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
|
||||||
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
|
|
||||||
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
|
|
||||||
+ { MODKEY|ShiftMask, XK_f, fullscreen, {0} },
|
|
||||||
{ MODKEY, XK_space, setlayout, {0} },
|
|
||||||
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
|
||||||
{ MODKEY, XK_0, view, {.ui = ~0 } },
|
|
||||||
diff --git a/dwm.c b/dwm.c
|
|
||||||
index 4465af1..04b1e06 100644
|
|
||||||
--- a/dwm.c
|
|
||||||
+++ b/dwm.c
|
|
||||||
@@ -199,6 +199,7 @@ static void sendmon(Client *c, Monitor *m);
|
|
||||||
static void setclientstate(Client *c, long state);
|
|
||||||
static void setfocus(Client *c);
|
|
||||||
static void setfullscreen(Client *c, int fullscreen);
|
|
||||||
+static void fullscreen(const Arg *arg);
|
|
||||||
static void setlayout(const Arg *arg);
|
|
||||||
static void setmfact(const Arg *arg);
|
|
||||||
static void setup(void);
|
|
||||||
@@ -1497,6 +1498,19 @@ setfullscreen(Client *c, int fullscreen)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+Layout *last_layout;
|
|
||||||
+void
|
|
||||||
+fullscreen(const Arg *arg)
|
|
||||||
+{
|
|
||||||
+ if (selmon->showbar) {
|
|
||||||
+ for(last_layout = (Layout *)layouts; last_layout != selmon->lt[selmon->sellt]; last_layout++);
|
|
||||||
+ setlayout(&((Arg) { .v = &layouts[2] }));
|
|
||||||
+ } else {
|
|
||||||
+ setlayout(&((Arg) { .v = last_layout }));
|
|
||||||
+ }
|
|
||||||
+ togglebar(arg);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
void
|
|
||||||
setlayout(const Arg *arg)
|
|
||||||
{
|
|
||||||
--
|
|
||||||
2.22.0
|
|
|
@ -1,73 +0,0 @@
|
||||||
From b04bb473cf9818277d33a591f7fe2dfae96afaaf Mon Sep 17 00:00:00 2001
|
|
||||||
From: Joshua Haase <hahj87@gmail.com>
|
|
||||||
Date: Mon, 15 Aug 2016 17:06:18 -0500
|
|
||||||
Subject: [PATCH] Apply modified gridmode patch.
|
|
||||||
|
|
||||||
---
|
|
||||||
config.def.h | 3 +++
|
|
||||||
layouts.c | 27 +++++++++++++++++++++++++++
|
|
||||||
2 files changed, 30 insertions(+)
|
|
||||||
create mode 100644 layouts.c
|
|
||||||
|
|
||||||
diff --git a/config.def.h b/config.def.h
|
|
||||||
index a9ac303..30b7c4a 100644
|
|
||||||
--- a/config.def.h
|
|
||||||
+++ b/config.def.h
|
|
||||||
@@ -36,11 +36,13 @@ static const float mfact = 0.55; /* factor of master area size [0.05..0.95]
|
|
||||||
static const int nmaster = 1; /* number of clients in master area */
|
|
||||||
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
|
|
||||||
|
|
||||||
+#include "layouts.c"
|
|
||||||
static const Layout layouts[] = {
|
|
||||||
/* symbol arrange function */
|
|
||||||
{ "[]=", tile }, /* first entry is default */
|
|
||||||
{ "><>", NULL }, /* no layout function means floating behavior */
|
|
||||||
{ "[M]", monocle },
|
|
||||||
+ { "HHH", grid },
|
|
||||||
};
|
|
||||||
|
|
||||||
/* key definitions */
|
|
||||||
@@ -76,6 +78,7 @@ static Key keys[] = {
|
|
||||||
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
|
||||||
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
|
|
||||||
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
|
|
||||||
+ { MODKEY, XK_g, setlayout, {.v = &layouts[3]} },
|
|
||||||
{ MODKEY, XK_space, setlayout, {0} },
|
|
||||||
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
|
||||||
{ MODKEY, XK_0, view, {.ui = ~0 } },
|
|
||||||
diff --git a/layouts.c b/layouts.c
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..d26acf3
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/layouts.c
|
|
||||||
@@ -0,0 +1,27 @@
|
|
||||||
+void
|
|
||||||
+grid(Monitor *m) {
|
|
||||||
+ unsigned int i, n, cx, cy, cw, ch, aw, ah, cols, rows;
|
|
||||||
+ Client *c;
|
|
||||||
+
|
|
||||||
+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next))
|
|
||||||
+ n++;
|
|
||||||
+
|
|
||||||
+ /* grid dimensions */
|
|
||||||
+ for(rows = 0; rows <= n/2; rows++)
|
|
||||||
+ if(rows*rows >= n)
|
|
||||||
+ break;
|
|
||||||
+ cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows;
|
|
||||||
+
|
|
||||||
+ /* window geoms (cell height/width) */
|
|
||||||
+ ch = m->wh / (rows ? rows : 1);
|
|
||||||
+ cw = m->ww / (cols ? cols : 1);
|
|
||||||
+ for(i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
|
|
||||||
+ cx = m->wx + (i / rows) * cw;
|
|
||||||
+ cy = m->wy + (i % rows) * ch;
|
|
||||||
+ /* adjust height/width of last row/column's windows */
|
|
||||||
+ ah = ((i + 1) % rows == 0) ? m->wh - ch * rows : 0;
|
|
||||||
+ aw = (i >= rows * (cols - 1)) ? m->ww - cw * cols : 0;
|
|
||||||
+ resize(c, cx, cy, cw - 2 * c->bw + aw, ch - 2 * c->bw + ah, False);
|
|
||||||
+ i++;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
--
|
|
||||||
2.14.1
|
|
||||||
|
|
|
@ -1,217 +0,0 @@
|
||||||
From e61a957ff8b7e14219b5fbaab9da794b722e7874 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Hai Nguyen <hhai2105@gmail.com>
|
|
||||||
Date: Fri, 10 Dec 2021 21:45:00 -0500
|
|
||||||
Subject: [PATCH] add Keychord struct, change keypress() and grabkeys() to be
|
|
||||||
able to grab a sequence of keystroke
|
|
||||||
|
|
||||||
---
|
|
||||||
config.def.h | 67 ++++++++++++++++++++++++++------------------------
|
|
||||||
dwm.c | 69 ++++++++++++++++++++++++++++++++++++++++------------
|
|
||||||
2 files changed, 88 insertions(+), 48 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/config.def.h b/config.def.h
|
|
||||||
index a2ac963..15a3e05 100644
|
|
||||||
--- a/config.def.h
|
|
||||||
+++ b/config.def.h
|
|
||||||
@@ -46,11 +46,12 @@ static const Layout layouts[] = {
|
|
||||||
|
|
||||||
/* key definitions */
|
|
||||||
#define MODKEY Mod1Mask
|
|
||||||
-#define TAGKEYS(KEY,TAG) \
|
|
||||||
- { MODKEY, KEY, view, {.ui = 1 << TAG} }, \
|
|
||||||
- { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
|
|
||||||
- { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
|
|
||||||
- { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
|
|
||||||
+
|
|
||||||
+#define TAGKEYS(KEY,TAG) \
|
|
||||||
+ {1, {{MODKEY, KEY}}, view, {.ui = 1 << TAG} }, \
|
|
||||||
+ {1, {{MODKEY|ControlMask, KEY}}, toggleview, {.ui = 1 << TAG} }, \
|
|
||||||
+ {1, {{MODKEY|ShiftMask, KEY}}, tag, {.ui = 1 << TAG} }, \
|
|
||||||
+ {1, {{MODKEY|ControlMask|ShiftMask, KEY}}, toggletag, {.ui = 1 << TAG} },
|
|
||||||
|
|
||||||
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
|
|
||||||
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
|
||||||
@@ -59,32 +60,34 @@ static const Layout layouts[] = {
|
|
||||||
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
|
|
||||||
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
|
|
||||||
static const char *termcmd[] = { "st", NULL };
|
|
||||||
+static const char *emacs[] = { "emacs", NULL };
|
|
||||||
|
|
||||||
-static Key keys[] = {
|
|
||||||
- /* modifier key function argument */
|
|
||||||
- { MODKEY, XK_p, spawn, {.v = dmenucmd } },
|
|
||||||
- { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
|
|
||||||
- { MODKEY, XK_b, togglebar, {0} },
|
|
||||||
- { MODKEY, XK_j, focusstack, {.i = +1 } },
|
|
||||||
- { MODKEY, XK_k, focusstack, {.i = -1 } },
|
|
||||||
- { MODKEY, XK_i, incnmaster, {.i = +1 } },
|
|
||||||
- { MODKEY, XK_d, incnmaster, {.i = -1 } },
|
|
||||||
- { MODKEY, XK_h, setmfact, {.f = -0.05} },
|
|
||||||
- { MODKEY, XK_l, setmfact, {.f = +0.05} },
|
|
||||||
- { MODKEY, XK_Return, zoom, {0} },
|
|
||||||
- { MODKEY, XK_Tab, view, {0} },
|
|
||||||
- { MODKEY|ShiftMask, XK_c, killclient, {0} },
|
|
||||||
- { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
|
||||||
- { MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
|
|
||||||
- { MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
|
|
||||||
- { MODKEY, XK_space, setlayout, {0} },
|
|
||||||
- { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
|
||||||
- { MODKEY, XK_0, view, {.ui = ~0 } },
|
|
||||||
- { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
|
|
||||||
- { MODKEY, XK_comma, focusmon, {.i = -1 } },
|
|
||||||
- { MODKEY, XK_period, focusmon, {.i = +1 } },
|
|
||||||
- { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
|
|
||||||
- { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
|
|
||||||
+static Keychord keychords[] = {
|
|
||||||
+ /* Keys function argument */
|
|
||||||
+ {1, {{MODKEY, XK_p}}, spawn, {.v = dmenucmd } },
|
|
||||||
+ {1, {{MODKEY|ShiftMask, XK_Return}}, spawn, {.v = termcmd } },
|
|
||||||
+ {2, {{MODKEY, XK_e}, {MODKEY, XK_e}}, spawn, {.v = termcmd } },
|
|
||||||
+ {1, {{MODKEY, XK_b}}, togglebar, {0} },
|
|
||||||
+ {1, {{MODKEY, XK_j}}, focusstack, {.i = +1 } },
|
|
||||||
+ {1, {{MODKEY, XK_k}}, focusstack, {.i = -1 } },
|
|
||||||
+ {1, {{MODKEY, XK_i}}, incnmaster, {.i = +1 } },
|
|
||||||
+ {1, {{MODKEY, XK_d}}, incnmaster, {.i = -1 } },
|
|
||||||
+ {1, {{MODKEY, XK_h}}, setmfact, {.f = -0.05} },
|
|
||||||
+ {1, {{MODKEY, XK_l}}, setmfact, {.f = +0.05} },
|
|
||||||
+ {1, {{MODKEY, XK_Return}}, zoom, {0} },
|
|
||||||
+ {1, {{MODKEY, XK_Tab}}, view, {0} },
|
|
||||||
+ {1, {{MODKEY|ShiftMask, XK_c}}, killclient, {0} },
|
|
||||||
+ {1, {{MODKEY, XK_t}}, setlayout, {.v = &layouts[0]} },
|
|
||||||
+ {1, {{MODKEY, XK_f}}, setlayout, {.v = &layouts[1]} },
|
|
||||||
+ {1, {{MODKEY, XK_m}}, setlayout, {.v = &layouts[2]} },
|
|
||||||
+ {1, {{MODKEY, XK_space}}, setlayout, {0} },
|
|
||||||
+ {1, {{MODKEY|ShiftMask, XK_space}}, togglefloating, {0} },
|
|
||||||
+ {1, {{MODKEY, XK_0}}, view, {.ui = ~0 } },
|
|
||||||
+ {1, {{MODKEY|ShiftMask, XK_0}}, tag, {.ui = ~0 } },
|
|
||||||
+ {1, {{MODKEY, XK_comma}}, focusmon, {.i = -1 } },
|
|
||||||
+ {1, {{MODKEY, XK_period}}, focusmon, {.i = +1 } },
|
|
||||||
+ {1, {{MODKEY|ShiftMask, XK_comma}}, tagmon, {.i = -1 } },
|
|
||||||
+ {1, {{MODKEY|ShiftMask, XK_period}}, tagmon, {.i = +1 } },
|
|
||||||
TAGKEYS( XK_1, 0)
|
|
||||||
TAGKEYS( XK_2, 1)
|
|
||||||
TAGKEYS( XK_3, 2)
|
|
||||||
@@ -92,9 +95,9 @@ static Key keys[] = {
|
|
||||||
TAGKEYS( XK_5, 4)
|
|
||||||
TAGKEYS( XK_6, 5)
|
|
||||||
TAGKEYS( XK_7, 6)
|
|
||||||
- TAGKEYS( XK_8, 7)
|
|
||||||
+ TAGKEYS( XK_8, 7)
|
|
||||||
TAGKEYS( XK_9, 8)
|
|
||||||
- { MODKEY|ShiftMask, XK_q, quit, {0} },
|
|
||||||
+ {1, {{MODKEY|ShiftMask, XK_q}}, quit, {0} },
|
|
||||||
};
|
|
||||||
|
|
||||||
/* button definitions */
|
|
||||||
diff --git a/dwm.c b/dwm.c
|
|
||||||
index 5e4d494..56c4661 100644
|
|
||||||
--- a/dwm.c
|
|
||||||
+++ b/dwm.c
|
|
||||||
@@ -102,9 +102,14 @@ struct Client {
|
|
||||||
typedef struct {
|
|
||||||
unsigned int mod;
|
|
||||||
KeySym keysym;
|
|
||||||
+} Key;
|
|
||||||
+
|
|
||||||
+typedef struct {
|
|
||||||
+ unsigned int n;
|
|
||||||
+ const Key keys[5];
|
|
||||||
void (*func)(const Arg *);
|
|
||||||
const Arg arg;
|
|
||||||
-} Key;
|
|
||||||
+} Keychord;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const char *symbol;
|
|
||||||
@@ -268,6 +273,7 @@ static Display *dpy;
|
|
||||||
static Drw *drw;
|
|
||||||
static Monitor *mons, *selmon;
|
|
||||||
static Window root, wmcheckwin;
|
|
||||||
+unsigned int currentkey = 0;
|
|
||||||
|
|
||||||
/* configuration, allows nested code to access above variables */
|
|
||||||
#include "config.h"
|
|
||||||
@@ -951,16 +957,16 @@ grabkeys(void)
|
|
||||||
{
|
|
||||||
updatenumlockmask();
|
|
||||||
{
|
|
||||||
- unsigned int i, j;
|
|
||||||
+ unsigned int i, k;
|
|
||||||
unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
|
|
||||||
KeyCode code;
|
|
||||||
|
|
||||||
XUngrabKey(dpy, AnyKey, AnyModifier, root);
|
|
||||||
- for (i = 0; i < LENGTH(keys); i++)
|
|
||||||
- if ((code = XKeysymToKeycode(dpy, keys[i].keysym)))
|
|
||||||
- for (j = 0; j < LENGTH(modifiers); j++)
|
|
||||||
- XGrabKey(dpy, code, keys[i].mod | modifiers[j], root,
|
|
||||||
- True, GrabModeAsync, GrabModeAsync);
|
|
||||||
+ for (i = 0; i < LENGTH(keychords); i++)
|
|
||||||
+ if ((code = XKeysymToKeycode(dpy, keychords[i].keys[currentkey].keysym)))
|
|
||||||
+ for (k = 0; k < LENGTH(modifiers); k++)
|
|
||||||
+ XGrabKey(dpy, code, keychords[i].keys[currentkey].mod | modifiers[k], root,
|
|
||||||
+ True, GrabModeAsync, GrabModeAsync);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -986,17 +992,48 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info)
|
|
||||||
void
|
|
||||||
keypress(XEvent *e)
|
|
||||||
{
|
|
||||||
- unsigned int i;
|
|
||||||
+ XEvent event = *e;
|
|
||||||
+ Keychord *keychord;
|
|
||||||
+ unsigned int ran = 0;
|
|
||||||
KeySym keysym;
|
|
||||||
XKeyEvent *ev;
|
|
||||||
-
|
|
||||||
- ev = &e->xkey;
|
|
||||||
- keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
|
|
||||||
- for (i = 0; i < LENGTH(keys); i++)
|
|
||||||
- if (keysym == keys[i].keysym
|
|
||||||
- && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
|
|
||||||
- && keys[i].func)
|
|
||||||
- keys[i].func(&(keys[i].arg));
|
|
||||||
+ Keychord *newoptions;
|
|
||||||
+ Keychord *oldoptions = (Keychord *)malloc(sizeof(keychords));
|
|
||||||
+
|
|
||||||
+ memcpy(oldoptions, keychords, sizeof(keychords));
|
|
||||||
+ size_t numoption = 0;
|
|
||||||
+ while(!ran){
|
|
||||||
+ ev = &event.xkey;
|
|
||||||
+ keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
|
|
||||||
+ newoptions = (Keychord *)malloc(0);
|
|
||||||
+ numoption = 0;
|
|
||||||
+ for (keychord = oldoptions; keychord->n != 0 && currentkey < 5; keychord = (Keychord *)((char *)keychord + sizeof(Keychord))){
|
|
||||||
+ if(keysym == keychord->keys[currentkey].keysym
|
|
||||||
+ && CLEANMASK(keychord->keys[currentkey].mod) == CLEANMASK(ev->state)
|
|
||||||
+ && keychord->func){
|
|
||||||
+ if(keychord->n == currentkey +1){
|
|
||||||
+ keychord->func(&(keychord->arg));
|
|
||||||
+ ran = 1;
|
|
||||||
+ }else{
|
|
||||||
+ numoption++;
|
|
||||||
+ newoptions = (Keychord *)realloc(newoptions, numoption * sizeof(Keychord));
|
|
||||||
+ memcpy((char *)newoptions + (numoption -1) * sizeof(Keychord),keychord, sizeof(Keychord));
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ currentkey++;
|
|
||||||
+ if(numoption == 0)
|
|
||||||
+ break;
|
|
||||||
+ grabkeys();
|
|
||||||
+ while (running && !XNextEvent(dpy, &event) && !ran)
|
|
||||||
+ if(event.type == KeyPress)
|
|
||||||
+ break;
|
|
||||||
+ free(oldoptions);
|
|
||||||
+ oldoptions = newoptions;
|
|
||||||
+ }
|
|
||||||
+ free(newoptions);
|
|
||||||
+ currentkey = 0;
|
|
||||||
+ grabkeys();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
--
|
|
||||||
2.34.1
|
|
||||||
|
|
|
@ -1,95 +0,0 @@
|
||||||
From 9a4037dc0ef56f91c009317e78e9e3790dafbb58 Mon Sep 17 00:00:00 2001
|
|
||||||
From: BrunoCooper17 <BrunoCooper17@outlook.com>
|
|
||||||
Date: Mon, 15 Nov 2021 14:04:53 -0600
|
|
||||||
Subject: [PATCH] MoveStack patch
|
|
||||||
|
|
||||||
This plugin allows you to move clients around in the stack and swap them
|
|
||||||
with the master. It emulates the behavior off mod+shift+j and mod+shift+k
|
|
||||||
in Xmonad. movestack(+1) will swap the client with the current focus with
|
|
||||||
the next client. movestack(-1) will swap the client with the current focus
|
|
||||||
with the previous client.
|
|
||||||
---
|
|
||||||
config.def.h | 3 +++
|
|
||||||
movestack.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
2 files changed, 51 insertions(+)
|
|
||||||
create mode 100644 movestack.c
|
|
||||||
|
|
||||||
diff --git a/config.def.h b/config.def.h
|
|
||||||
index a2ac963..33efa5b 100644
|
|
||||||
--- a/config.def.h
|
|
||||||
+++ b/config.def.h
|
|
||||||
@@ -60,6 +60,7 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn()
|
|
||||||
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
|
|
||||||
static const char *termcmd[] = { "st", NULL };
|
|
||||||
|
|
||||||
+#include "movestack.c"
|
|
||||||
static Key keys[] = {
|
|
||||||
/* modifier key function argument */
|
|
||||||
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
|
|
||||||
@@ -71,6 +72,8 @@ static Key keys[] = {
|
|
||||||
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
|
|
||||||
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
|
|
||||||
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
|
|
||||||
+ { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } },
|
|
||||||
+ { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } },
|
|
||||||
{ MODKEY, XK_Return, zoom, {0} },
|
|
||||||
{ MODKEY, XK_Tab, view, {0} },
|
|
||||||
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
|
|
||||||
diff --git a/movestack.c b/movestack.c
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..520f4ae
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/movestack.c
|
|
||||||
@@ -0,0 +1,48 @@
|
|
||||||
+void
|
|
||||||
+movestack(const Arg *arg) {
|
|
||||||
+ Client *c = NULL, *p = NULL, *pc = NULL, *i;
|
|
||||||
+
|
|
||||||
+ if(arg->i > 0) {
|
|
||||||
+ /* find the client after selmon->sel */
|
|
||||||
+ for(c = selmon->sel->next; c && (!ISVISIBLE(c) || c->isfloating); c = c->next);
|
|
||||||
+ if(!c)
|
|
||||||
+ for(c = selmon->clients; c && (!ISVISIBLE(c) || c->isfloating); c = c->next);
|
|
||||||
+
|
|
||||||
+ }
|
|
||||||
+ else {
|
|
||||||
+ /* find the client before selmon->sel */
|
|
||||||
+ for(i = selmon->clients; i != selmon->sel; i = i->next)
|
|
||||||
+ if(ISVISIBLE(i) && !i->isfloating)
|
|
||||||
+ c = i;
|
|
||||||
+ if(!c)
|
|
||||||
+ for(; i; i = i->next)
|
|
||||||
+ if(ISVISIBLE(i) && !i->isfloating)
|
|
||||||
+ c = i;
|
|
||||||
+ }
|
|
||||||
+ /* find the client before selmon->sel and c */
|
|
||||||
+ for(i = selmon->clients; i && (!p || !pc); i = i->next) {
|
|
||||||
+ if(i->next == selmon->sel)
|
|
||||||
+ p = i;
|
|
||||||
+ if(i->next == c)
|
|
||||||
+ pc = i;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* swap c and selmon->sel selmon->clients in the selmon->clients list */
|
|
||||||
+ if(c && c != selmon->sel) {
|
|
||||||
+ Client *temp = selmon->sel->next==c?selmon->sel:selmon->sel->next;
|
|
||||||
+ selmon->sel->next = c->next==selmon->sel?c:c->next;
|
|
||||||
+ c->next = temp;
|
|
||||||
+
|
|
||||||
+ if(p && p != c)
|
|
||||||
+ p->next = c;
|
|
||||||
+ if(pc && pc != selmon->sel)
|
|
||||||
+ pc->next = selmon->sel;
|
|
||||||
+
|
|
||||||
+ if(selmon->sel == selmon->clients)
|
|
||||||
+ selmon->clients = c;
|
|
||||||
+ else if(c == selmon->clients)
|
|
||||||
+ selmon->clients = selmon->sel;
|
|
||||||
+
|
|
||||||
+ arrange(selmon);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
\ No newline at end of file
|
|
||||||
--
|
|
||||||
2.33.1
|
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
From 700b0bdea872f4c00182b2bd925b41fe03f8d222 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Aidan Hall <aidan.hall@outlook.com>
|
|
||||||
Date: Tue, 2 Jun 2020 14:41:53 +0000
|
|
||||||
Subject: [PATCH] Prevents hiding the border if layout is floating.
|
|
||||||
|
|
||||||
---
|
|
||||||
dwm.c | 8 ++++++++
|
|
||||||
1 file changed, 8 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/dwm.c b/dwm.c
|
|
||||||
index 4465af1..2dd959d 100644
|
|
||||||
--- a/dwm.c
|
|
||||||
+++ b/dwm.c
|
|
||||||
@@ -1282,6 +1282,14 @@ resizeclient(Client *c, int x, int y, int w, int h)
|
|
||||||
c->oldw = c->w; c->w = wc.width = w;
|
|
||||||
c->oldh = c->h; c->h = wc.height = h;
|
|
||||||
wc.border_width = c->bw;
|
|
||||||
+ if (((nexttiled(c->mon->clients) == c && !nexttiled(c->next))
|
|
||||||
+ || &monocle == c->mon->lt[c->mon->sellt]->arrange)
|
|
||||||
+ && !c->isfullscreen && !c->isfloating
|
|
||||||
+ && NULL != c->mon->lt[c->mon->sellt]->arrange) {
|
|
||||||
+ c->w = wc.width += c->bw * 2;
|
|
||||||
+ c->h = wc.height += c->bw * 2;
|
|
||||||
+ wc.border_width = 0;
|
|
||||||
+ }
|
|
||||||
XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
|
|
||||||
configure(c);
|
|
||||||
XSync(dpy, False);
|
|
||||||
--
|
|
||||||
2.26.2
|
|
||||||
|
|
|
@ -1,177 +0,0 @@
|
||||||
diff --git a/dwm.c b/dwm.c
|
|
||||||
index 664c527..ac8e4ec 100644
|
|
||||||
--- a/dwm.c
|
|
||||||
+++ b/dwm.c
|
|
||||||
@@ -111,6 +111,7 @@ typedef struct {
|
|
||||||
void (*arrange)(Monitor *);
|
|
||||||
} Layout;
|
|
||||||
|
|
||||||
+typedef struct Pertag Pertag;
|
|
||||||
struct Monitor {
|
|
||||||
char ltsymbol[16];
|
|
||||||
float mfact;
|
|
||||||
@@ -130,6 +131,7 @@ struct Monitor {
|
|
||||||
Monitor *next;
|
|
||||||
Window barwin;
|
|
||||||
const Layout *lt[2];
|
|
||||||
+ Pertag *pertag;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
@@ -272,6 +274,15 @@ static Window root, wmcheckwin;
|
|
||||||
/* configuration, allows nested code to access above variables */
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
+struct Pertag {
|
|
||||||
+ unsigned int curtag, prevtag; /* current and previous tag */
|
|
||||||
+ int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */
|
|
||||||
+ float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */
|
|
||||||
+ unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */
|
|
||||||
+ const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */
|
|
||||||
+ int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
/* compile-time check if all tags fit into an unsigned int bit array. */
|
|
||||||
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
|
|
||||||
|
|
||||||
@@ -632,6 +643,7 @@ Monitor *
|
|
||||||
createmon(void)
|
|
||||||
{
|
|
||||||
Monitor *m;
|
|
||||||
+ unsigned int i;
|
|
||||||
|
|
||||||
m = ecalloc(1, sizeof(Monitor));
|
|
||||||
m->tagset[0] = m->tagset[1] = 1;
|
|
||||||
@@ -642,6 +654,20 @@ createmon(void)
|
|
||||||
m->lt[0] = &layouts[0];
|
|
||||||
m->lt[1] = &layouts[1 % LENGTH(layouts)];
|
|
||||||
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
|
|
||||||
+ m->pertag = ecalloc(1, sizeof(Pertag));
|
|
||||||
+ m->pertag->curtag = m->pertag->prevtag = 1;
|
|
||||||
+
|
|
||||||
+ for (i = 0; i <= LENGTH(tags); i++) {
|
|
||||||
+ m->pertag->nmasters[i] = m->nmaster;
|
|
||||||
+ m->pertag->mfacts[i] = m->mfact;
|
|
||||||
+
|
|
||||||
+ m->pertag->ltidxs[i][0] = m->lt[0];
|
|
||||||
+ m->pertag->ltidxs[i][1] = m->lt[1];
|
|
||||||
+ m->pertag->sellts[i] = m->sellt;
|
|
||||||
+
|
|
||||||
+ m->pertag->showbars[i] = m->showbar;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -967,7 +993,7 @@ grabkeys(void)
|
|
||||||
void
|
|
||||||
incnmaster(const Arg *arg)
|
|
||||||
{
|
|
||||||
- selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
|
|
||||||
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0);
|
|
||||||
arrange(selmon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1502,9 +1528,9 @@ void
|
|
||||||
setlayout(const Arg *arg)
|
|
||||||
{
|
|
||||||
if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
|
|
||||||
- selmon->sellt ^= 1;
|
|
||||||
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1;
|
|
||||||
if (arg && arg->v)
|
|
||||||
- selmon->lt[selmon->sellt] = (Layout *)arg->v;
|
|
||||||
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v;
|
|
||||||
strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
|
|
||||||
if (selmon->sel)
|
|
||||||
arrange(selmon);
|
|
||||||
@@ -1523,7 +1549,7 @@ setmfact(const Arg *arg)
|
|
||||||
f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
|
|
||||||
if (f < 0.05 || f > 0.95)
|
|
||||||
return;
|
|
||||||
- selmon->mfact = f;
|
|
||||||
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f;
|
|
||||||
arrange(selmon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1702,7 +1728,7 @@ tile(Monitor *m)
|
|
||||||
void
|
|
||||||
togglebar(const Arg *arg)
|
|
||||||
{
|
|
||||||
- selmon->showbar = !selmon->showbar;
|
|
||||||
+ selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar;
|
|
||||||
updatebarpos(selmon);
|
|
||||||
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
|
|
||||||
arrange(selmon);
|
|
||||||
@@ -1741,9 +1767,33 @@ void
|
|
||||||
toggleview(const Arg *arg)
|
|
||||||
{
|
|
||||||
unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
|
|
||||||
+ int i;
|
|
||||||
|
|
||||||
if (newtagset) {
|
|
||||||
selmon->tagset[selmon->seltags] = newtagset;
|
|
||||||
+
|
|
||||||
+ if (newtagset == ~0) {
|
|
||||||
+ selmon->pertag->prevtag = selmon->pertag->curtag;
|
|
||||||
+ selmon->pertag->curtag = 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* test if the user did not select the same tag */
|
|
||||||
+ if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) {
|
|
||||||
+ selmon->pertag->prevtag = selmon->pertag->curtag;
|
|
||||||
+ for (i = 0; !(newtagset & 1 << i); i++) ;
|
|
||||||
+ selmon->pertag->curtag = i + 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* apply settings for this view */
|
|
||||||
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
|
|
||||||
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
|
|
||||||
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
|
|
||||||
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
|
|
||||||
+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
|
|
||||||
+
|
|
||||||
+ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
|
|
||||||
+ togglebar(NULL);
|
|
||||||
+
|
|
||||||
focus(NULL);
|
|
||||||
arrange(selmon);
|
|
||||||
}
|
|
||||||
@@ -2038,11 +2088,37 @@ updatewmhints(Client *c)
|
|
||||||
void
|
|
||||||
view(const Arg *arg)
|
|
||||||
{
|
|
||||||
+ int i;
|
|
||||||
+ unsigned int tmptag;
|
|
||||||
+
|
|
||||||
if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
|
|
||||||
return;
|
|
||||||
selmon->seltags ^= 1; /* toggle sel tagset */
|
|
||||||
- if (arg->ui & TAGMASK)
|
|
||||||
+ if (arg->ui & TAGMASK) {
|
|
||||||
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
|
|
||||||
+ selmon->pertag->prevtag = selmon->pertag->curtag;
|
|
||||||
+
|
|
||||||
+ if (arg->ui == ~0)
|
|
||||||
+ selmon->pertag->curtag = 0;
|
|
||||||
+ else {
|
|
||||||
+ for (i = 0; !(arg->ui & 1 << i); i++) ;
|
|
||||||
+ selmon->pertag->curtag = i + 1;
|
|
||||||
+ }
|
|
||||||
+ } else {
|
|
||||||
+ tmptag = selmon->pertag->prevtag;
|
|
||||||
+ selmon->pertag->prevtag = selmon->pertag->curtag;
|
|
||||||
+ selmon->pertag->curtag = tmptag;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
|
|
||||||
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
|
|
||||||
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
|
|
||||||
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
|
|
||||||
+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
|
|
||||||
+
|
|
||||||
+ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
|
|
||||||
+ togglebar(NULL);
|
|
||||||
+
|
|
||||||
focus(NULL);
|
|
||||||
arrange(selmon);
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
diff --git a/config.def.h b/config.def.h
|
|
||||||
index 7054c06..9b5d5b8 100644
|
|
||||||
--- a/config.def.h
|
|
||||||
+++ b/config.def.h
|
|
||||||
@@ -76,6 +76,7 @@ static Key keys[] = {
|
|
||||||
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
|
|
||||||
{ MODKEY, XK_space, setlayout, {0} },
|
|
||||||
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
|
||||||
+ { MODKEY, XK_s, togglesticky, {0} },
|
|
||||||
{ MODKEY, XK_0, view, {.ui = ~0 } },
|
|
||||||
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
|
|
||||||
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
|
|
||||||
diff --git a/dwm.c b/dwm.c
|
|
||||||
index 0362114..0ef5c7f 100644
|
|
||||||
--- a/dwm.c
|
|
||||||
+++ b/dwm.c
|
|
||||||
@@ -49,7 +49,7 @@
|
|
||||||
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
|
|
||||||
#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
|
|
||||||
* MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
|
|
||||||
-#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
|
|
||||||
+#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]) || C->issticky)
|
|
||||||
#define LENGTH(X) (sizeof X / sizeof X[0])
|
|
||||||
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
|
||||||
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
|
|
||||||
@@ -92,7 +92,7 @@ struct Client {
|
|
||||||
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
|
|
||||||
int bw, oldbw;
|
|
||||||
unsigned int tags;
|
|
||||||
- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
|
|
||||||
+ int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, issticky;
|
|
||||||
Client *next;
|
|
||||||
Client *snext;
|
|
||||||
Monitor *mon;
|
|
||||||
@@ -211,6 +211,7 @@ static void tagmon(const Arg *arg);
|
|
||||||
static void tile(Monitor *);
|
|
||||||
static void togglebar(const Arg *arg);
|
|
||||||
static void togglefloating(const Arg *arg);
|
|
||||||
+static void togglesticky(const Arg *arg);
|
|
||||||
static void toggletag(const Arg *arg);
|
|
||||||
static void toggleview(const Arg *arg);
|
|
||||||
static void unfocus(Client *c, int setfocus);
|
|
||||||
@@ -1713,6 +1714,15 @@ togglefloating(const Arg *arg)
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
+togglesticky(const Arg *arg)
|
|
||||||
+{
|
|
||||||
+ if (!selmon->sel)
|
|
||||||
+ return;
|
|
||||||
+ selmon->sel->issticky = !selmon->sel->issticky;
|
|
||||||
+ arrange(selmon);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
toggletag(const Arg *arg)
|
|
||||||
{
|
|
||||||
unsigned int newtags;
|
|
|
@ -1,763 +0,0 @@
|
||||||
diff --git a/config.def.h b/config.def.h
|
|
||||||
index a2ac963..4be4c06 100644
|
|
||||||
--- a/config.def.h
|
|
||||||
+++ b/config.def.h
|
|
||||||
@@ -2,9 +2,14 @@
|
|
||||||
|
|
||||||
/* appearance */
|
|
||||||
static const unsigned int borderpx = 1; /* border pixel of windows */
|
|
||||||
-static const unsigned int snap = 32; /* snap pixel */
|
|
||||||
-static const int showbar = 1; /* 0 means no bar */
|
|
||||||
-static const int topbar = 1; /* 0 means bottom bar */
|
|
||||||
+static const unsigned int snap = 32; /* snap pixel */
|
|
||||||
+static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */
|
|
||||||
+static const unsigned int systrayonleft = 0; /* 0: systray in the right corner, >0: systray on left of status text */
|
|
||||||
+static const unsigned int systrayspacing = 2; /* systray spacing */
|
|
||||||
+static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/
|
|
||||||
+static const int showsystray = 1; /* 0 means no systray */
|
|
||||||
+static const int showbar = 1; /* 0 means no bar */
|
|
||||||
+static const int topbar = 1; /* 0 means bottom bar */
|
|
||||||
static const char *fonts[] = { "monospace:size=10" };
|
|
||||||
static const char dmenufont[] = "monospace:size=10";
|
|
||||||
static const char col_gray1[] = "#222222";
|
|
||||||
@@ -101,8 +106,8 @@ static Key keys[] = {
|
|
||||||
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
|
|
||||||
static Button buttons[] = {
|
|
||||||
/* click event mask button function argument */
|
|
||||||
- { ClkLtSymbol, 0, Button1, setlayout, {0} },
|
|
||||||
- { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
|
|
||||||
+ { ClkTagBar, MODKEY, Button1, tag, {0} },
|
|
||||||
+ { ClkTagBar, MODKEY, Button3, toggletag, {0} },
|
|
||||||
{ ClkWinTitle, 0, Button2, zoom, {0} },
|
|
||||||
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
|
|
||||||
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
|
|
||||||
diff --git a/dwm.c b/dwm.c
|
|
||||||
index a96f33c..941c1c0 100644
|
|
||||||
--- a/dwm.c
|
|
||||||
+++ b/dwm.c
|
|
||||||
@@ -57,12 +57,27 @@
|
|
||||||
#define TAGMASK ((1 << LENGTH(tags)) - 1)
|
|
||||||
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
|
|
||||||
|
|
||||||
+#define SYSTEM_TRAY_REQUEST_DOCK 0
|
|
||||||
+/* XEMBED messages */
|
|
||||||
+#define XEMBED_EMBEDDED_NOTIFY 0
|
|
||||||
+#define XEMBED_WINDOW_ACTIVATE 1
|
|
||||||
+#define XEMBED_FOCUS_IN 4
|
|
||||||
+#define XEMBED_MODALITY_ON 10
|
|
||||||
+#define XEMBED_MAPPED (1 << 0)
|
|
||||||
+#define XEMBED_WINDOW_ACTIVATE 1
|
|
||||||
+#define XEMBED_WINDOW_DEACTIVATE 2
|
|
||||||
+#define VERSION_MAJOR 0
|
|
||||||
+#define VERSION_MINOR 0
|
|
||||||
+#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR
|
|
||||||
+
|
|
||||||
/* enums */
|
|
||||||
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
|
|
||||||
enum { SchemeNorm, SchemeSel }; /* color schemes */
|
|
||||||
enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
|
|
||||||
+ NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz,
|
|
||||||
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
|
|
||||||
NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
|
|
||||||
+enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */
|
|
||||||
enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
|
|
||||||
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
|
|
||||||
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
|
|
||||||
@@ -141,6 +156,12 @@ typedef struct {
|
|
||||||
int monitor;
|
|
||||||
} Rule;
|
|
||||||
|
|
||||||
+typedef struct Systray Systray;
|
|
||||||
+struct Systray {
|
|
||||||
+ Window win;
|
|
||||||
+ Client *icons;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
/* function declarations */
|
|
||||||
static void applyrules(Client *c);
|
|
||||||
static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
|
|
||||||
@@ -172,6 +193,7 @@ static void focusstack(const Arg *arg);
|
|
||||||
static Atom getatomprop(Client *c, Atom prop);
|
|
||||||
static int getrootptr(int *x, int *y);
|
|
||||||
static long getstate(Window w);
|
|
||||||
+static unsigned int getsystraywidth();
|
|
||||||
static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
|
|
||||||
static void grabbuttons(Client *c, int focused);
|
|
||||||
static void grabkeys(void);
|
|
||||||
@@ -189,13 +211,16 @@ static void pop(Client *);
|
|
||||||
static void propertynotify(XEvent *e);
|
|
||||||
static void quit(const Arg *arg);
|
|
||||||
static Monitor *recttomon(int x, int y, int w, int h);
|
|
||||||
+static void removesystrayicon(Client *i);
|
|
||||||
static void resize(Client *c, int x, int y, int w, int h, int interact);
|
|
||||||
+static void resizebarwin(Monitor *m);
|
|
||||||
static void resizeclient(Client *c, int x, int y, int w, int h);
|
|
||||||
static void resizemouse(const Arg *arg);
|
|
||||||
+static void resizerequest(XEvent *e);
|
|
||||||
static void restack(Monitor *m);
|
|
||||||
static void run(void);
|
|
||||||
static void scan(void);
|
|
||||||
-static int sendevent(Client *c, Atom proto);
|
|
||||||
+static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4);
|
|
||||||
static void sendmon(Client *c, Monitor *m);
|
|
||||||
static void setclientstate(Client *c, long state);
|
|
||||||
static void setfocus(Client *c);
|
|
||||||
@@ -207,6 +232,7 @@ static void seturgent(Client *c, int urg);
|
|
||||||
static void showhide(Client *c);
|
|
||||||
static void sigchld(int unused);
|
|
||||||
static void spawn(const Arg *arg);
|
|
||||||
+static Monitor *systraytomon(Monitor *m);
|
|
||||||
static void tag(const Arg *arg);
|
|
||||||
static void tagmon(const Arg *arg);
|
|
||||||
static void tile(Monitor *);
|
|
||||||
@@ -224,18 +250,23 @@ static int updategeom(void);
|
|
||||||
static void updatenumlockmask(void);
|
|
||||||
static void updatesizehints(Client *c);
|
|
||||||
static void updatestatus(void);
|
|
||||||
+static void updatesystray(void);
|
|
||||||
+static void updatesystrayicongeom(Client *i, int w, int h);
|
|
||||||
+static void updatesystrayiconstate(Client *i, XPropertyEvent *ev);
|
|
||||||
static void updatetitle(Client *c);
|
|
||||||
static void updatewindowtype(Client *c);
|
|
||||||
static void updatewmhints(Client *c);
|
|
||||||
static void view(const Arg *arg);
|
|
||||||
static Client *wintoclient(Window w);
|
|
||||||
static Monitor *wintomon(Window w);
|
|
||||||
+static Client *wintosystrayicon(Window w);
|
|
||||||
static int xerror(Display *dpy, XErrorEvent *ee);
|
|
||||||
static int xerrordummy(Display *dpy, XErrorEvent *ee);
|
|
||||||
static int xerrorstart(Display *dpy, XErrorEvent *ee);
|
|
||||||
static void zoom(const Arg *arg);
|
|
||||||
|
|
||||||
/* variables */
|
|
||||||
+static Systray *systray = NULL;
|
|
||||||
static const char broken[] = "broken";
|
|
||||||
static char stext[256];
|
|
||||||
static int screen;
|
|
||||||
@@ -258,9 +289,10 @@ static void (*handler[LASTEvent]) (XEvent *) = {
|
|
||||||
[MapRequest] = maprequest,
|
|
||||||
[MotionNotify] = motionnotify,
|
|
||||||
[PropertyNotify] = propertynotify,
|
|
||||||
+ [ResizeRequest] = resizerequest,
|
|
||||||
[UnmapNotify] = unmapnotify
|
|
||||||
};
|
|
||||||
-static Atom wmatom[WMLast], netatom[NetLast];
|
|
||||||
+static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast];
|
|
||||||
static int running = 1;
|
|
||||||
static Cur *cursor[CurLast];
|
|
||||||
static Clr **scheme;
|
|
||||||
@@ -440,7 +472,7 @@ buttonpress(XEvent *e)
|
|
||||||
arg.ui = 1 << i;
|
|
||||||
} else if (ev->x < x + blw)
|
|
||||||
click = ClkLtSymbol;
|
|
||||||
- else if (ev->x > selmon->ww - (int)TEXTW(stext))
|
|
||||||
+ else if (ev->x > selmon->ww - (int)TEXTW(stext) - getsystraywidth())
|
|
||||||
click = ClkStatusText;
|
|
||||||
else
|
|
||||||
click = ClkWinTitle;
|
|
||||||
@@ -483,7 +515,14 @@ cleanup(void)
|
|
||||||
XUngrabKey(dpy, AnyKey, AnyModifier, root);
|
|
||||||
while (mons)
|
|
||||||
cleanupmon(mons);
|
|
||||||
- for (i = 0; i < CurLast; i++)
|
|
||||||
+
|
|
||||||
+ if (showsystray) {
|
|
||||||
+ XUnmapWindow(dpy, systray->win);
|
|
||||||
+ XDestroyWindow(dpy, systray->win);
|
|
||||||
+ free(systray);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ for (i = 0; i < CurLast; i++)
|
|
||||||
drw_cur_free(drw, cursor[i]);
|
|
||||||
for (i = 0; i < LENGTH(colors); i++)
|
|
||||||
free(scheme[i]);
|
|
||||||
@@ -513,9 +552,58 @@ cleanupmon(Monitor *mon)
|
|
||||||
void
|
|
||||||
clientmessage(XEvent *e)
|
|
||||||
{
|
|
||||||
+ XWindowAttributes wa;
|
|
||||||
+ XSetWindowAttributes swa;
|
|
||||||
XClientMessageEvent *cme = &e->xclient;
|
|
||||||
Client *c = wintoclient(cme->window);
|
|
||||||
|
|
||||||
+ if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) {
|
|
||||||
+ /* add systray icons */
|
|
||||||
+ if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) {
|
|
||||||
+ if (!(c = (Client *)calloc(1, sizeof(Client))))
|
|
||||||
+ die("fatal: could not malloc() %u bytes\n", sizeof(Client));
|
|
||||||
+ if (!(c->win = cme->data.l[2])) {
|
|
||||||
+ free(c);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+ c->mon = selmon;
|
|
||||||
+ c->next = systray->icons;
|
|
||||||
+ systray->icons = c;
|
|
||||||
+ if (!XGetWindowAttributes(dpy, c->win, &wa)) {
|
|
||||||
+ /* use sane defaults */
|
|
||||||
+ wa.width = bh;
|
|
||||||
+ wa.height = bh;
|
|
||||||
+ wa.border_width = 0;
|
|
||||||
+ }
|
|
||||||
+ c->x = c->oldx = c->y = c->oldy = 0;
|
|
||||||
+ c->w = c->oldw = wa.width;
|
|
||||||
+ c->h = c->oldh = wa.height;
|
|
||||||
+ c->oldbw = wa.border_width;
|
|
||||||
+ c->bw = 0;
|
|
||||||
+ c->isfloating = True;
|
|
||||||
+ /* reuse tags field as mapped status */
|
|
||||||
+ c->tags = 1;
|
|
||||||
+ updatesizehints(c);
|
|
||||||
+ updatesystrayicongeom(c, wa.width, wa.height);
|
|
||||||
+ XAddToSaveSet(dpy, c->win);
|
|
||||||
+ XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask);
|
|
||||||
+ XReparentWindow(dpy, c->win, systray->win, 0, 0);
|
|
||||||
+ /* use parents background color */
|
|
||||||
+ swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
|
|
||||||
+ XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa);
|
|
||||||
+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
|
|
||||||
+ /* FIXME not sure if I have to send these events, too */
|
|
||||||
+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
|
|
||||||
+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
|
|
||||||
+ sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0 , systray->win, XEMBED_EMBEDDED_VERSION);
|
|
||||||
+ XSync(dpy, False);
|
|
||||||
+ resizebarwin(selmon);
|
|
||||||
+ updatesystray();
|
|
||||||
+ setclientstate(c, NormalState);
|
|
||||||
+ }
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (!c)
|
|
||||||
return;
|
|
||||||
if (cme->message_type == netatom[NetWMState]) {
|
|
||||||
@@ -568,7 +656,7 @@ configurenotify(XEvent *e)
|
|
||||||
for (c = m->clients; c; c = c->next)
|
|
||||||
if (c->isfullscreen)
|
|
||||||
resizeclient(c, m->mx, m->my, m->mw, m->mh);
|
|
||||||
- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
|
|
||||||
+ resizebarwin(m);
|
|
||||||
}
|
|
||||||
focus(NULL);
|
|
||||||
arrange(NULL);
|
|
||||||
@@ -653,6 +741,11 @@ destroynotify(XEvent *e)
|
|
||||||
|
|
||||||
if ((c = wintoclient(ev->window)))
|
|
||||||
unmanage(c, 1);
|
|
||||||
+ else if ((c = wintosystrayicon(ev->window))) {
|
|
||||||
+ removesystrayicon(c);
|
|
||||||
+ resizebarwin(selmon);
|
|
||||||
+ updatesystray();
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
@@ -696,7 +789,7 @@ dirtomon(int dir)
|
|
||||||
void
|
|
||||||
drawbar(Monitor *m)
|
|
||||||
{
|
|
||||||
- int x, w, tw = 0;
|
|
||||||
+ int x, w, tw = 0, stw = 0;
|
|
||||||
int boxs = drw->fonts->h / 9;
|
|
||||||
int boxw = drw->fonts->h / 6 + 2;
|
|
||||||
unsigned int i, occ = 0, urg = 0;
|
|
||||||
@@ -705,13 +798,17 @@ drawbar(Monitor *m)
|
|
||||||
if (!m->showbar)
|
|
||||||
return;
|
|
||||||
|
|
||||||
+ if(showsystray && m == systraytomon(m) && !systrayonleft)
|
|
||||||
+ stw = getsystraywidth();
|
|
||||||
+
|
|
||||||
/* draw status first so it can be overdrawn by tags later */
|
|
||||||
if (m == selmon) { /* status is only drawn on selected monitor */
|
|
||||||
drw_setscheme(drw, scheme[SchemeNorm]);
|
|
||||||
- tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
|
|
||||||
- drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
|
|
||||||
+ tw = TEXTW(stext) - lrpad / 2 + 2; /* 2px extra right padding */
|
|
||||||
+ drw_text(drw, m->ww - tw - stw, 0, tw, bh, lrpad / 2 - 2, stext, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ resizebarwin(m);
|
|
||||||
for (c = m->clients; c; c = c->next) {
|
|
||||||
occ |= c->tags;
|
|
||||||
if (c->isurgent)
|
|
||||||
@@ -732,7 +829,7 @@ drawbar(Monitor *m)
|
|
||||||
drw_setscheme(drw, scheme[SchemeNorm]);
|
|
||||||
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
|
|
||||||
|
|
||||||
- if ((w = m->ww - tw - x) > bh) {
|
|
||||||
+ if ((w = m->ww - tw - stw - x) > bh) {
|
|
||||||
if (m->sel) {
|
|
||||||
drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
|
|
||||||
drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
|
|
||||||
@@ -743,7 +840,7 @@ drawbar(Monitor *m)
|
|
||||||
drw_rect(drw, x, 0, w, bh, 1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- drw_map(drw, m->barwin, 0, 0, m->ww, bh);
|
|
||||||
+ drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
@@ -780,8 +877,11 @@ expose(XEvent *e)
|
|
||||||
Monitor *m;
|
|
||||||
XExposeEvent *ev = &e->xexpose;
|
|
||||||
|
|
||||||
- if (ev->count == 0 && (m = wintomon(ev->window)))
|
|
||||||
+ if (ev->count == 0 && (m = wintomon(ev->window))) {
|
|
||||||
drawbar(m);
|
|
||||||
+ if (m == selmon)
|
|
||||||
+ updatesystray();
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
@@ -867,9 +967,17 @@ getatomprop(Client *c, Atom prop)
|
|
||||||
unsigned char *p = NULL;
|
|
||||||
Atom da, atom = None;
|
|
||||||
|
|
||||||
- if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM,
|
|
||||||
+ /* FIXME getatomprop should return the number of items and a pointer to
|
|
||||||
+ * the stored data instead of this workaround */
|
|
||||||
+ Atom req = XA_ATOM;
|
|
||||||
+ if (prop == xatom[XembedInfo])
|
|
||||||
+ req = xatom[XembedInfo];
|
|
||||||
+
|
|
||||||
+ if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req,
|
|
||||||
&da, &di, &dl, &dl, &p) == Success && p) {
|
|
||||||
atom = *(Atom *)p;
|
|
||||||
+ if (da == xatom[XembedInfo] && dl == 2)
|
|
||||||
+ atom = ((Atom *)p)[1];
|
|
||||||
XFree(p);
|
|
||||||
}
|
|
||||||
return atom;
|
|
||||||
@@ -903,6 +1011,16 @@ getstate(Window w)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
+unsigned int
|
|
||||||
+getsystraywidth()
|
|
||||||
+{
|
|
||||||
+ unsigned int w = 0;
|
|
||||||
+ Client *i;
|
|
||||||
+ if(showsystray)
|
|
||||||
+ for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ;
|
|
||||||
+ return w ? w + systrayspacing : 1;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
int
|
|
||||||
gettextprop(Window w, Atom atom, char *text, unsigned int size)
|
|
||||||
{
|
|
||||||
@@ -1007,7 +1125,8 @@ killclient(const Arg *arg)
|
|
||||||
{
|
|
||||||
if (!selmon->sel)
|
|
||||||
return;
|
|
||||||
- if (!sendevent(selmon->sel, wmatom[WMDelete])) {
|
|
||||||
+
|
|
||||||
+ if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) {
|
|
||||||
XGrabServer(dpy);
|
|
||||||
XSetErrorHandler(xerrordummy);
|
|
||||||
XSetCloseDownMode(dpy, DestroyAll);
|
|
||||||
@@ -1096,6 +1215,13 @@ maprequest(XEvent *e)
|
|
||||||
static XWindowAttributes wa;
|
|
||||||
XMapRequestEvent *ev = &e->xmaprequest;
|
|
||||||
|
|
||||||
+ Client *i;
|
|
||||||
+ if ((i = wintosystrayicon(ev->window))) {
|
|
||||||
+ sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION);
|
|
||||||
+ resizebarwin(selmon);
|
|
||||||
+ updatesystray();
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (!XGetWindowAttributes(dpy, ev->window, &wa))
|
|
||||||
return;
|
|
||||||
if (wa.override_redirect)
|
|
||||||
@@ -1219,7 +1345,18 @@ propertynotify(XEvent *e)
|
|
||||||
Window trans;
|
|
||||||
XPropertyEvent *ev = &e->xproperty;
|
|
||||||
|
|
||||||
- if ((ev->window == root) && (ev->atom == XA_WM_NAME))
|
|
||||||
+ if ((c = wintosystrayicon(ev->window))) {
|
|
||||||
+ if (ev->atom == XA_WM_NORMAL_HINTS) {
|
|
||||||
+ updatesizehints(c);
|
|
||||||
+ updatesystrayicongeom(c, c->w, c->h);
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ updatesystrayiconstate(c, ev);
|
|
||||||
+ resizebarwin(selmon);
|
|
||||||
+ updatesystray();
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if ((ev->window == root) && (ev->atom == XA_WM_NAME))
|
|
||||||
updatestatus();
|
|
||||||
else if (ev->state == PropertyDelete)
|
|
||||||
return; /* ignore */
|
|
||||||
@@ -1269,6 +1406,19 @@ recttomon(int x, int y, int w, int h)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
+void
|
|
||||||
+removesystrayicon(Client *i)
|
|
||||||
+{
|
|
||||||
+ Client **ii;
|
|
||||||
+
|
|
||||||
+ if (!showsystray || !i)
|
|
||||||
+ return;
|
|
||||||
+ for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next);
|
|
||||||
+ if (ii)
|
|
||||||
+ *ii = i->next;
|
|
||||||
+ free(i);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
void
|
|
||||||
resize(Client *c, int x, int y, int w, int h, int interact)
|
|
||||||
{
|
|
||||||
@@ -1276,6 +1426,14 @@ resize(Client *c, int x, int y, int w, int h, int interact)
|
|
||||||
resizeclient(c, x, y, w, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
+void
|
|
||||||
+resizebarwin(Monitor *m) {
|
|
||||||
+ unsigned int w = m->ww;
|
|
||||||
+ if (showsystray && m == systraytomon(m) && !systrayonleft)
|
|
||||||
+ w -= getsystraywidth();
|
|
||||||
+ XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
void
|
|
||||||
resizeclient(Client *c, int x, int y, int w, int h)
|
|
||||||
{
|
|
||||||
@@ -1348,6 +1506,19 @@ resizemouse(const Arg *arg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+void
|
|
||||||
+resizerequest(XEvent *e)
|
|
||||||
+{
|
|
||||||
+ XResizeRequestEvent *ev = &e->xresizerequest;
|
|
||||||
+ Client *i;
|
|
||||||
+
|
|
||||||
+ if ((i = wintosystrayicon(ev->window))) {
|
|
||||||
+ updatesystrayicongeom(i, ev->width, ev->height);
|
|
||||||
+ resizebarwin(selmon);
|
|
||||||
+ updatesystray();
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
void
|
|
||||||
restack(Monitor *m)
|
|
||||||
{
|
|
||||||
@@ -1437,26 +1608,37 @@ setclientstate(Client *c, long state)
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
-sendevent(Client *c, Atom proto)
|
|
||||||
+sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
- Atom *protocols;
|
|
||||||
+ Atom *protocols, mt;
|
|
||||||
int exists = 0;
|
|
||||||
XEvent ev;
|
|
||||||
|
|
||||||
- if (XGetWMProtocols(dpy, c->win, &protocols, &n)) {
|
|
||||||
- while (!exists && n--)
|
|
||||||
- exists = protocols[n] == proto;
|
|
||||||
- XFree(protocols);
|
|
||||||
+ if (proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) {
|
|
||||||
+ mt = wmatom[WMProtocols];
|
|
||||||
+ if (XGetWMProtocols(dpy, w, &protocols, &n)) {
|
|
||||||
+ while (!exists && n--)
|
|
||||||
+ exists = protocols[n] == proto;
|
|
||||||
+ XFree(protocols);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
+ else {
|
|
||||||
+ exists = True;
|
|
||||||
+ mt = proto;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (exists) {
|
|
||||||
ev.type = ClientMessage;
|
|
||||||
- ev.xclient.window = c->win;
|
|
||||||
- ev.xclient.message_type = wmatom[WMProtocols];
|
|
||||||
+ ev.xclient.window = w;
|
|
||||||
+ ev.xclient.message_type = mt;
|
|
||||||
ev.xclient.format = 32;
|
|
||||||
- ev.xclient.data.l[0] = proto;
|
|
||||||
- ev.xclient.data.l[1] = CurrentTime;
|
|
||||||
- XSendEvent(dpy, c->win, False, NoEventMask, &ev);
|
|
||||||
+ ev.xclient.data.l[0] = d0;
|
|
||||||
+ ev.xclient.data.l[1] = d1;
|
|
||||||
+ ev.xclient.data.l[2] = d2;
|
|
||||||
+ ev.xclient.data.l[3] = d3;
|
|
||||||
+ ev.xclient.data.l[4] = d4;
|
|
||||||
+ XSendEvent(dpy, w, False, mask, &ev);
|
|
||||||
}
|
|
||||||
return exists;
|
|
||||||
}
|
|
||||||
@@ -1470,7 +1652,7 @@ setfocus(Client *c)
|
|
||||||
XA_WINDOW, 32, PropModeReplace,
|
|
||||||
(unsigned char *) &(c->win), 1);
|
|
||||||
}
|
|
||||||
- sendevent(c, wmatom[WMTakeFocus]);
|
|
||||||
+ sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
@@ -1558,15 +1740,22 @@ setup(void)
|
|
||||||
wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False);
|
|
||||||
wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
|
|
||||||
netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);
|
|
||||||
- netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
|
|
||||||
- netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
|
|
||||||
+ netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
|
|
||||||
+ netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False);
|
|
||||||
+ netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False);
|
|
||||||
+ netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False);
|
|
||||||
+ netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", False);
|
|
||||||
+ netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
|
|
||||||
netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
|
|
||||||
netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
|
|
||||||
netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
|
|
||||||
netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
|
|
||||||
netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
|
|
||||||
netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
|
|
||||||
- /* init cursors */
|
|
||||||
+ xatom[Manager] = XInternAtom(dpy, "MANAGER", False);
|
|
||||||
+ xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False);
|
|
||||||
+ xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False);
|
|
||||||
+ /* init cursors */
|
|
||||||
cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
|
|
||||||
cursor[CurResize] = drw_cur_create(drw, XC_sizing);
|
|
||||||
cursor[CurMove] = drw_cur_create(drw, XC_fleur);
|
|
||||||
@@ -1574,6 +1763,8 @@ setup(void)
|
|
||||||
scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
|
|
||||||
for (i = 0; i < LENGTH(colors); i++)
|
|
||||||
scheme[i] = drw_scm_create(drw, colors[i], 3);
|
|
||||||
+ /* init system tray */
|
|
||||||
+ updatesystray();
|
|
||||||
/* init bars */
|
|
||||||
updatebars();
|
|
||||||
updatestatus();
|
|
||||||
@@ -1707,7 +1898,18 @@ togglebar(const Arg *arg)
|
|
||||||
{
|
|
||||||
selmon->showbar = !selmon->showbar;
|
|
||||||
updatebarpos(selmon);
|
|
||||||
- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
|
|
||||||
+ resizebarwin(selmon);
|
|
||||||
+ if (showsystray) {
|
|
||||||
+ XWindowChanges wc;
|
|
||||||
+ if (!selmon->showbar)
|
|
||||||
+ wc.y = -bh;
|
|
||||||
+ else if (selmon->showbar) {
|
|
||||||
+ wc.y = 0;
|
|
||||||
+ if (!selmon->topbar)
|
|
||||||
+ wc.y = selmon->mh - bh;
|
|
||||||
+ }
|
|
||||||
+ XConfigureWindow(dpy, systray->win, CWY, &wc);
|
|
||||||
+ }
|
|
||||||
arrange(selmon);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1802,11 +2004,18 @@ unmapnotify(XEvent *e)
|
|
||||||
else
|
|
||||||
unmanage(c, 0);
|
|
||||||
}
|
|
||||||
+ else if ((c = wintosystrayicon(ev->window))) {
|
|
||||||
+ /* KLUDGE! sometimes icons occasionally unmap their windows, but do
|
|
||||||
+ * _not_ destroy them. We map those windows back */
|
|
||||||
+ XMapRaised(dpy, c->win);
|
|
||||||
+ updatesystray();
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
updatebars(void)
|
|
||||||
{
|
|
||||||
+ unsigned int w;
|
|
||||||
Monitor *m;
|
|
||||||
XSetWindowAttributes wa = {
|
|
||||||
.override_redirect = True,
|
|
||||||
@@ -1817,10 +2026,15 @@ updatebars(void)
|
|
||||||
for (m = mons; m; m = m->next) {
|
|
||||||
if (m->barwin)
|
|
||||||
continue;
|
|
||||||
- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
|
|
||||||
+ w = m->ww;
|
|
||||||
+ if (showsystray && m == systraytomon(m))
|
|
||||||
+ w -= getsystraywidth();
|
|
||||||
+ m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, DefaultDepth(dpy, screen),
|
|
||||||
CopyFromParent, DefaultVisual(dpy, screen),
|
|
||||||
CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
|
|
||||||
XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
|
|
||||||
+ if (showsystray && m == systraytomon(m))
|
|
||||||
+ XMapRaised(dpy, systray->win);
|
|
||||||
XMapRaised(dpy, m->barwin);
|
|
||||||
XSetClassHint(dpy, m->barwin, &ch);
|
|
||||||
}
|
|
||||||
@@ -1996,6 +2210,125 @@ updatestatus(void)
|
|
||||||
if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
|
|
||||||
strcpy(stext, "dwm-"VERSION);
|
|
||||||
drawbar(selmon);
|
|
||||||
+ updatesystray();
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+updatesystrayicongeom(Client *i, int w, int h)
|
|
||||||
+{
|
|
||||||
+ if (i) {
|
|
||||||
+ i->h = bh;
|
|
||||||
+ if (w == h)
|
|
||||||
+ i->w = bh;
|
|
||||||
+ else if (h == bh)
|
|
||||||
+ i->w = w;
|
|
||||||
+ else
|
|
||||||
+ i->w = (int) ((float)bh * ((float)w / (float)h));
|
|
||||||
+ applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False);
|
|
||||||
+ /* force icons into the systray dimensions if they don't want to */
|
|
||||||
+ if (i->h > bh) {
|
|
||||||
+ if (i->w == i->h)
|
|
||||||
+ i->w = bh;
|
|
||||||
+ else
|
|
||||||
+ i->w = (int) ((float)bh * ((float)i->w / (float)i->h));
|
|
||||||
+ i->h = bh;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+updatesystrayiconstate(Client *i, XPropertyEvent *ev)
|
|
||||||
+{
|
|
||||||
+ long flags;
|
|
||||||
+ int code = 0;
|
|
||||||
+
|
|
||||||
+ if (!showsystray || !i || ev->atom != xatom[XembedInfo] ||
|
|
||||||
+ !(flags = getatomprop(i, xatom[XembedInfo])))
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ if (flags & XEMBED_MAPPED && !i->tags) {
|
|
||||||
+ i->tags = 1;
|
|
||||||
+ code = XEMBED_WINDOW_ACTIVATE;
|
|
||||||
+ XMapRaised(dpy, i->win);
|
|
||||||
+ setclientstate(i, NormalState);
|
|
||||||
+ }
|
|
||||||
+ else if (!(flags & XEMBED_MAPPED) && i->tags) {
|
|
||||||
+ i->tags = 0;
|
|
||||||
+ code = XEMBED_WINDOW_DEACTIVATE;
|
|
||||||
+ XUnmapWindow(dpy, i->win);
|
|
||||||
+ setclientstate(i, WithdrawnState);
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ return;
|
|
||||||
+ sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0,
|
|
||||||
+ systray->win, XEMBED_EMBEDDED_VERSION);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+updatesystray(void)
|
|
||||||
+{
|
|
||||||
+ XSetWindowAttributes wa;
|
|
||||||
+ XWindowChanges wc;
|
|
||||||
+ Client *i;
|
|
||||||
+ Monitor *m = systraytomon(NULL);
|
|
||||||
+ unsigned int x = m->mx + m->mw;
|
|
||||||
+ unsigned int sw = TEXTW(stext) - lrpad + systrayspacing;
|
|
||||||
+ unsigned int w = 1;
|
|
||||||
+
|
|
||||||
+ if (!showsystray)
|
|
||||||
+ return;
|
|
||||||
+ if (systrayonleft)
|
|
||||||
+ x -= sw + lrpad / 2;
|
|
||||||
+ if (!systray) {
|
|
||||||
+ /* init systray */
|
|
||||||
+ if (!(systray = (Systray *)calloc(1, sizeof(Systray))))
|
|
||||||
+ die("fatal: could not malloc() %u bytes\n", sizeof(Systray));
|
|
||||||
+ systray->win = XCreateSimpleWindow(dpy, root, x, m->by, w, bh, 0, 0, scheme[SchemeSel][ColBg].pixel);
|
|
||||||
+ wa.event_mask = ButtonPressMask | ExposureMask;
|
|
||||||
+ wa.override_redirect = True;
|
|
||||||
+ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
|
|
||||||
+ XSelectInput(dpy, systray->win, SubstructureNotifyMask);
|
|
||||||
+ XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32,
|
|
||||||
+ PropModeReplace, (unsigned char *)&netatom[NetSystemTrayOrientationHorz], 1);
|
|
||||||
+ XChangeWindowAttributes(dpy, systray->win, CWEventMask|CWOverrideRedirect|CWBackPixel, &wa);
|
|
||||||
+ XMapRaised(dpy, systray->win);
|
|
||||||
+ XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime);
|
|
||||||
+ if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) {
|
|
||||||
+ sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0);
|
|
||||||
+ XSync(dpy, False);
|
|
||||||
+ }
|
|
||||||
+ else {
|
|
||||||
+ fprintf(stderr, "dwm: unable to obtain system tray.\n");
|
|
||||||
+ free(systray);
|
|
||||||
+ systray = NULL;
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ for (w = 0, i = systray->icons; i; i = i->next) {
|
|
||||||
+ /* make sure the background color stays the same */
|
|
||||||
+ wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
|
|
||||||
+ XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa);
|
|
||||||
+ XMapRaised(dpy, i->win);
|
|
||||||
+ w += systrayspacing;
|
|
||||||
+ i->x = w;
|
|
||||||
+ XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h);
|
|
||||||
+ w += i->w;
|
|
||||||
+ if (i->mon != m)
|
|
||||||
+ i->mon = m;
|
|
||||||
+ }
|
|
||||||
+ w = w ? w + systrayspacing : 1;
|
|
||||||
+ x -= w;
|
|
||||||
+ XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh);
|
|
||||||
+ wc.x = x; wc.y = m->by; wc.width = w; wc.height = bh;
|
|
||||||
+ wc.stack_mode = Above; wc.sibling = m->barwin;
|
|
||||||
+ XConfigureWindow(dpy, systray->win, CWX|CWY|CWWidth|CWHeight|CWSibling|CWStackMode, &wc);
|
|
||||||
+ XMapWindow(dpy, systray->win);
|
|
||||||
+ XMapSubwindows(dpy, systray->win);
|
|
||||||
+ /* redraw background */
|
|
||||||
+ XSetForeground(dpy, drw->gc, scheme[SchemeNorm][ColBg].pixel);
|
|
||||||
+ XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh);
|
|
||||||
+ XSync(dpy, False);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
@@ -2063,6 +2396,16 @@ wintoclient(Window w)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
+Client *
|
|
||||||
+wintosystrayicon(Window w) {
|
|
||||||
+ Client *i = NULL;
|
|
||||||
+
|
|
||||||
+ if (!showsystray || !w)
|
|
||||||
+ return i;
|
|
||||||
+ for (i = systray->icons; i && i->win != w; i = i->next) ;
|
|
||||||
+ return i;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
Monitor *
|
|
||||||
wintomon(Window w)
|
|
||||||
{
|
|
||||||
@@ -2116,6 +2459,22 @@ xerrorstart(Display *dpy, XErrorEvent *ee)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
+Monitor *
|
|
||||||
+systraytomon(Monitor *m) {
|
|
||||||
+ Monitor *t;
|
|
||||||
+ int i, n;
|
|
||||||
+ if(!systraypinning) {
|
|
||||||
+ if(!m)
|
|
||||||
+ return selmon;
|
|
||||||
+ return m == selmon ? m : NULL;
|
|
||||||
+ }
|
|
||||||
+ for(n = 1, t = mons; t && t->next; n++, t = t->next) ;
|
|
||||||
+ for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) ;
|
|
||||||
+ if(systraypinningfailfirst && n < systraypinning)
|
|
||||||
+ return mons;
|
|
||||||
+ return t;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
void
|
|
||||||
zoom(const Arg *arg)
|
|
||||||
{
|
|
6
renovate.json
Normal file
6
renovate.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
|
"extends": [
|
||||||
|
"config:base"
|
||||||
|
]
|
||||||
|
}
|
Binary file not shown.
Before Width: | Height: | Size: 2.3 MiB |
Binary file not shown.
Before Width: | Height: | Size: 1.4 MiB |
Binary file not shown.
Before Width: | Height: | Size: 1 MiB |
Binary file not shown.
Before Width: | Height: | Size: 1.5 MiB |
51
src/Makefile
51
src/Makefile
|
@ -1,51 +0,0 @@
|
||||||
# dwm - dynamic window manager
|
|
||||||
# See LICENSE file for copyright and license details.
|
|
||||||
|
|
||||||
include config.mk
|
|
||||||
|
|
||||||
SRC = drw.c dwm.c util.c
|
|
||||||
OBJ = ${SRC:.c=.o}
|
|
||||||
|
|
||||||
all: options dwm
|
|
||||||
|
|
||||||
options:
|
|
||||||
@echo dwm build options:
|
|
||||||
@echo "CFLAGS = ${CFLAGS}"
|
|
||||||
@echo "LDFLAGS = ${LDFLAGS}"
|
|
||||||
@echo "CC = ${CC}"
|
|
||||||
|
|
||||||
.c.o:
|
|
||||||
${CC} -c ${CFLAGS} $<
|
|
||||||
|
|
||||||
${OBJ}: config.h config.mk
|
|
||||||
|
|
||||||
config.h:
|
|
||||||
cp config.def.h $@
|
|
||||||
|
|
||||||
dwm: ${OBJ}
|
|
||||||
${CC} -o $@ ${OBJ} ${LDFLAGS}
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
|
|
||||||
|
|
||||||
dist: clean
|
|
||||||
mkdir -p dwm-${VERSION}
|
|
||||||
cp -R LICENSE Makefile README config.def.h config.mk\
|
|
||||||
dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION}
|
|
||||||
tar -cf dwm-${VERSION}.tar dwm-${VERSION}
|
|
||||||
gzip dwm-${VERSION}.tar
|
|
||||||
rm -rf dwm-${VERSION}
|
|
||||||
|
|
||||||
install: all
|
|
||||||
mkdir -p ${DESTDIR}${PREFIX}/bin
|
|
||||||
cp -f dwm ${DESTDIR}${PREFIX}/bin
|
|
||||||
chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
|
|
||||||
mkdir -p ${DESTDIR}${MANPREFIX}/man1
|
|
||||||
sed "s/VERSION/${VERSION}/g" < ../dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
|
|
||||||
chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1
|
|
||||||
|
|
||||||
uninstall:
|
|
||||||
rm -f ${DESTDIR}${PREFIX}/bin/dwm\
|
|
||||||
${DESTDIR}${MANPREFIX}/man1/dwm.1
|
|
||||||
|
|
||||||
.PHONY: all options clean dist install uninstall
|
|
44
src/actions.h
Normal file
44
src/actions.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
//
|
||||||
|
// Created by anas on 10/31/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ACTIONS_H
|
||||||
|
#define ACTIONS_H
|
||||||
|
|
||||||
|
#include "archy_dwm.h"
|
||||||
|
|
||||||
|
static void focusmon(const Arg *arg);
|
||||||
|
|
||||||
|
static void fullscreen(const Arg *arg);
|
||||||
|
|
||||||
|
static void focusstack(const Arg *arg);
|
||||||
|
|
||||||
|
static void tagmon(const Arg *arg);
|
||||||
|
|
||||||
|
static void incnmaster(const Arg *arg);
|
||||||
|
|
||||||
|
static void killclient(const Arg *arg);
|
||||||
|
|
||||||
|
static void movemouse(const Arg *arg);
|
||||||
|
|
||||||
|
static void togglebar(const Arg *arg);
|
||||||
|
|
||||||
|
static void togglesticky(const Arg *arg);
|
||||||
|
|
||||||
|
static void togglefloating(const Arg *arg);
|
||||||
|
|
||||||
|
static void setmfact(const Arg *arg);
|
||||||
|
|
||||||
|
static void view(const Arg *arg);
|
||||||
|
|
||||||
|
static void movestack(const Arg *arg);
|
||||||
|
|
||||||
|
static void setlayout(const Arg *arg);
|
||||||
|
|
||||||
|
static void tag(const Arg *arg);
|
||||||
|
|
||||||
|
static void zoom(const Arg *arg);
|
||||||
|
|
||||||
|
static void quit(const Arg *arg);
|
||||||
|
|
||||||
|
#endif //ACTIONS_H
|
2327
src/archy_dwm.c
Normal file
2327
src/archy_dwm.c
Normal file
File diff suppressed because it is too large
Load diff
273
src/archy_dwm.h
Normal file
273
src/archy_dwm.h
Normal file
|
@ -0,0 +1,273 @@
|
||||||
|
//
|
||||||
|
// Created by anas on 10/31/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ARCHY_DWM_H
|
||||||
|
#define ARCHY_DWM_H
|
||||||
|
|
||||||
|
/* enums */
|
||||||
|
enum {
|
||||||
|
CurNormal, CurResize, CurMove, CurLast
|
||||||
|
}; /* cursor */
|
||||||
|
enum {
|
||||||
|
SchemeNorm, SchemeSel, SchemeUrg
|
||||||
|
}; /* color schemes */
|
||||||
|
enum {
|
||||||
|
NetSupported, NetWMName, NetWMState, NetWMCheck,
|
||||||
|
NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz,
|
||||||
|
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
|
||||||
|
NetWMWindowTypeDialog, NetClientList, NetLast
|
||||||
|
}; /* EWMH atoms */
|
||||||
|
enum {
|
||||||
|
Manager, Xembed, XembedInfo, XLast
|
||||||
|
}; /* Xembed atoms */
|
||||||
|
enum {
|
||||||
|
WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast
|
||||||
|
}; /* default atoms */
|
||||||
|
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
int i;
|
||||||
|
unsigned int ui;
|
||||||
|
float f;
|
||||||
|
const void *v;
|
||||||
|
} Arg;
|
||||||
|
|
||||||
|
typedef struct Monitor Monitor;
|
||||||
|
typedef struct Client Client;
|
||||||
|
struct Client {
|
||||||
|
char name[256];
|
||||||
|
float mina, maxa;
|
||||||
|
int x, y, w, h;
|
||||||
|
int oldx, oldy, oldw, oldh;
|
||||||
|
int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid;
|
||||||
|
int bw, oldbw;
|
||||||
|
unsigned int tags;
|
||||||
|
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, issticky;
|
||||||
|
Client *next;
|
||||||
|
Client *snext;
|
||||||
|
Monitor *mon;
|
||||||
|
Window win;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *symbol;
|
||||||
|
|
||||||
|
void (*arrange)(Monitor *);
|
||||||
|
} Layout;
|
||||||
|
|
||||||
|
typedef struct Pertag Pertag;
|
||||||
|
struct Monitor {
|
||||||
|
char ltsymbol[16];
|
||||||
|
float mfact;
|
||||||
|
int nmaster;
|
||||||
|
int num;
|
||||||
|
int by; /* bar geometry */
|
||||||
|
int mx, my, mw, mh; /* screen size */
|
||||||
|
int wx, wy, ww, wh; /* window area */
|
||||||
|
unsigned int seltags;
|
||||||
|
unsigned int sellt;
|
||||||
|
unsigned int tagset[2];
|
||||||
|
int showbar;
|
||||||
|
int topbar;
|
||||||
|
Client *clients;
|
||||||
|
Client *sel;
|
||||||
|
Client *stack;
|
||||||
|
Monitor *next;
|
||||||
|
Window barwin;
|
||||||
|
const Layout *lt[2];
|
||||||
|
Pertag *pertag;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *class;
|
||||||
|
const char *instance;
|
||||||
|
const char *title;
|
||||||
|
unsigned int tags;
|
||||||
|
int isfloating;
|
||||||
|
int monitor;
|
||||||
|
} Rule;
|
||||||
|
|
||||||
|
typedef struct Systray Systray;
|
||||||
|
struct Systray {
|
||||||
|
Window win;
|
||||||
|
Client *icons;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* function declarations */
|
||||||
|
static void applyrules(Client *c);
|
||||||
|
|
||||||
|
static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
|
||||||
|
|
||||||
|
static void arrange(Monitor *m);
|
||||||
|
|
||||||
|
static void arrangemon(Monitor *m);
|
||||||
|
|
||||||
|
static void attach(Client *c);
|
||||||
|
|
||||||
|
static void attachstack(Client *c);
|
||||||
|
|
||||||
|
static void buttonpress(XEvent *e);
|
||||||
|
|
||||||
|
static void checkotherwm(void);
|
||||||
|
|
||||||
|
static void cleanup(void);
|
||||||
|
|
||||||
|
static void cleanupmon(Monitor *mon);
|
||||||
|
|
||||||
|
static void clientmessage(XEvent *e);
|
||||||
|
|
||||||
|
static void configure(Client *c);
|
||||||
|
|
||||||
|
static void configurenotify(XEvent *e);
|
||||||
|
|
||||||
|
static void configurerequest(XEvent *e);
|
||||||
|
|
||||||
|
static Monitor *createmon(void);
|
||||||
|
|
||||||
|
static void destroynotify(XEvent *e);
|
||||||
|
|
||||||
|
static void detach(Client *c);
|
||||||
|
|
||||||
|
static void detachstack(Client *c);
|
||||||
|
|
||||||
|
static Monitor *dirtomon(int dir);
|
||||||
|
|
||||||
|
static void drawbar(Monitor *m);
|
||||||
|
|
||||||
|
static void drawbars(void);
|
||||||
|
|
||||||
|
static void enternotify(XEvent *e);
|
||||||
|
|
||||||
|
static void expose(XEvent *e);
|
||||||
|
|
||||||
|
static void focus(Client *c);
|
||||||
|
|
||||||
|
static void focusin(XEvent *e);
|
||||||
|
|
||||||
|
static Atom getatomprop(Client *c, Atom prop);
|
||||||
|
|
||||||
|
static int getrootptr(int *x, int *y);
|
||||||
|
|
||||||
|
static long getstate(Window w);
|
||||||
|
|
||||||
|
static unsigned int getsystraywidth();
|
||||||
|
|
||||||
|
static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
|
||||||
|
|
||||||
|
static void grabbuttons(Client *c, int focused);
|
||||||
|
|
||||||
|
static void grabkeys(void);
|
||||||
|
|
||||||
|
static void keypress(XEvent *e);
|
||||||
|
|
||||||
|
static void manage(Window w, XWindowAttributes *wa);
|
||||||
|
|
||||||
|
static void mappingnotify(XEvent *e);
|
||||||
|
|
||||||
|
static void maprequest(XEvent *e);
|
||||||
|
|
||||||
|
static void monocle(Monitor *m);
|
||||||
|
|
||||||
|
static void motionnotify(XEvent *e);
|
||||||
|
|
||||||
|
static Client *nexttiled(Client *c);
|
||||||
|
|
||||||
|
static void pop(Client *);
|
||||||
|
|
||||||
|
static void propertynotify(XEvent *e);
|
||||||
|
|
||||||
|
static Monitor *recttomon(int x, int y, int w, int h);
|
||||||
|
|
||||||
|
static void removesystrayicon(Client *i);
|
||||||
|
|
||||||
|
static void resize(Client *c, int x, int y, int w, int h, int interact);
|
||||||
|
|
||||||
|
static void resizebarwin(Monitor *m);
|
||||||
|
|
||||||
|
static void resizeclient(Client *c, int x, int y, int w, int h);
|
||||||
|
|
||||||
|
static void resizemouse(const Arg *arg);
|
||||||
|
|
||||||
|
static void resizerequest(XEvent *e);
|
||||||
|
|
||||||
|
static void restack(Monitor *m);
|
||||||
|
|
||||||
|
static void run(void);
|
||||||
|
|
||||||
|
static void scan(void);
|
||||||
|
|
||||||
|
static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4);
|
||||||
|
|
||||||
|
static void sendmon(Client *c, Monitor *m);
|
||||||
|
|
||||||
|
static void setclientstate(Client *c, long state);
|
||||||
|
|
||||||
|
static void setfocus(Client *c);
|
||||||
|
|
||||||
|
static void setfullscreen(Client *c, int fullscreen);
|
||||||
|
|
||||||
|
static void setup(void);
|
||||||
|
|
||||||
|
static void seturgent(Client *c, int urg);
|
||||||
|
|
||||||
|
static void showhide(Client *c);
|
||||||
|
|
||||||
|
static void sigchld(int unused);
|
||||||
|
|
||||||
|
static Monitor *systraytomon(Monitor *m);
|
||||||
|
|
||||||
|
static void tile(Monitor *);
|
||||||
|
|
||||||
|
static void toggletag(const Arg *arg);
|
||||||
|
|
||||||
|
static void toggleview(const Arg *arg);
|
||||||
|
|
||||||
|
static void unfocus(Client *c, int setfocus);
|
||||||
|
|
||||||
|
static void unmanage(Client *c, int destroyed);
|
||||||
|
|
||||||
|
static void unmapnotify(XEvent *e);
|
||||||
|
|
||||||
|
static void updatebarpos(Monitor *m);
|
||||||
|
|
||||||
|
static void updatebars(void);
|
||||||
|
|
||||||
|
static void updateclientlist(void);
|
||||||
|
|
||||||
|
static int updategeom(void);
|
||||||
|
|
||||||
|
static void updatenumlockmask(void);
|
||||||
|
|
||||||
|
static void updatesizehints(Client *c);
|
||||||
|
|
||||||
|
static void updatestatus(void);
|
||||||
|
|
||||||
|
static void updatesystray(void);
|
||||||
|
|
||||||
|
static void updatesystrayicongeom(Client *i, int w, int h);
|
||||||
|
|
||||||
|
static void updatesystrayiconstate(Client *i, XPropertyEvent *ev);
|
||||||
|
|
||||||
|
static void updatetitle(Client *c);
|
||||||
|
|
||||||
|
static void updatewindowtype(Client *c);
|
||||||
|
|
||||||
|
static void updatewmhints(Client *c);
|
||||||
|
|
||||||
|
static Client *wintoclient(Window w);
|
||||||
|
|
||||||
|
static Monitor *wintomon(Window w);
|
||||||
|
|
||||||
|
static Client *wintosystrayicon(Window w);
|
||||||
|
|
||||||
|
static int xerror(Display *dpy, XErrorEvent *ee);
|
||||||
|
|
||||||
|
static int xerrordummy(Display *dpy, XErrorEvent *ee);
|
||||||
|
|
||||||
|
static int xerrorstart(Display *dpy, XErrorEvent *ee);
|
||||||
|
|
||||||
|
static void autostart_exec(void);
|
||||||
|
|
||||||
|
#endif //ARCHY_DWM_H
|
29
src/colors.h
29
src/colors.h
|
@ -1,29 +0,0 @@
|
||||||
#ifndef colors_H
|
|
||||||
#define colors_H
|
|
||||||
|
|
||||||
// #define wal "/home/anas/.cache/wal/colors-wal-dwm.h"
|
|
||||||
|
|
||||||
// #if __has_include(wal)
|
|
||||||
// #include wal
|
|
||||||
// #else
|
|
||||||
static const char norm_fg[] = "#e4ded4";
|
|
||||||
static const char norm_bg[] = "#191b1f";
|
|
||||||
static const char norm_border[] = "#282c34";
|
|
||||||
|
|
||||||
static const char sel_fg[] = "#e4ded4";
|
|
||||||
static const char sel_bg[] = "#3f2124";
|
|
||||||
static const char sel_border[] = "#e4ded4";
|
|
||||||
|
|
||||||
static const char urg_fg[] = "#e4ded4";
|
|
||||||
static const char urg_bg[] = "#313036";
|
|
||||||
static const char urg_border[] = "#312e36";
|
|
||||||
|
|
||||||
static const char *colors[][3] = {
|
|
||||||
/* fg bg border */
|
|
||||||
[SchemeNorm] = { norm_fg, norm_bg, norm_border }, // unfocused wins
|
|
||||||
[SchemeSel] = { sel_fg, sel_bg, sel_border }, // the focused win
|
|
||||||
[SchemeUrg] = { urg_fg, urg_bg, urg_border },
|
|
||||||
};
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
#endif // !colors.h
|
|
23
src/colors/defualt.h
Normal file
23
src/colors/defualt.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef colors_H
|
||||||
|
#define colors_H
|
||||||
|
|
||||||
|
static const char norm_fg[] = "#e4ded4";
|
||||||
|
static const char norm_bg[] = "#191b1f";
|
||||||
|
static const char norm_border[] = "#282c34";
|
||||||
|
|
||||||
|
static const char sel_fg[] = "#e4ded4";
|
||||||
|
static const char sel_bg[] = "#3f2124";
|
||||||
|
static const char sel_border[] = "#e4ded4";
|
||||||
|
|
||||||
|
static const char urg_fg[] = "#e4ded4";
|
||||||
|
static const char urg_bg[] = "#313036";
|
||||||
|
static const char urg_border[] = "#312e36";
|
||||||
|
|
||||||
|
static const char *colors[][3] = {
|
||||||
|
/* fg bg border */
|
||||||
|
[SchemeNorm] = {norm_fg, norm_bg, norm_border}, // unfocused wins
|
||||||
|
[SchemeSel] = {sel_fg, sel_bg, sel_border}, // the focused win
|
||||||
|
[SchemeUrg] = {urg_fg, urg_bg, urg_border},
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // colors_H
|
28
src/colors/dracula.h
Normal file
28
src/colors/dracula.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
//
|
||||||
|
// Created by anas on 10/31/22.
|
||||||
|
//
|
||||||
|
// inspired from: https://github.com/0x73hahd/dwm-config/blob/dev/source/colors/dracula.h
|
||||||
|
|
||||||
|
#ifndef DRACULA_H
|
||||||
|
#define DRACULA_H
|
||||||
|
|
||||||
|
static const char norm_fg[] = "#ff79c6";
|
||||||
|
static const char norm_bg[] = "#282a36";
|
||||||
|
static const char norm_border[] = "#282a36";
|
||||||
|
|
||||||
|
static const char sel_fg[] = "#ffb86c";
|
||||||
|
static const char sel_bg[] = "#282a36";
|
||||||
|
static const char sel_border[] = "#ffb86c";
|
||||||
|
|
||||||
|
static const char urg_fg[] = "#e4ded4";
|
||||||
|
static const char urg_bg[] = "#313036";
|
||||||
|
static const char urg_border[] = "#312e36";
|
||||||
|
|
||||||
|
static const char *colors[][3] = {
|
||||||
|
/* fg bg border */
|
||||||
|
[SchemeNorm] = {norm_fg, norm_bg, norm_border}, // unfocused wins
|
||||||
|
[SchemeSel] = {sel_fg, sel_bg, sel_border}, // the focused win
|
||||||
|
[SchemeUrg] = {urg_fg, urg_bg, urg_border},
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //DRACULA_H
|
26
src/colors/gruvbox_dark_hard.h
Normal file
26
src/colors/gruvbox_dark_hard.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
//
|
||||||
|
// Created by anas on 08/28/23.
|
||||||
|
//
|
||||||
|
#ifndef GRUVBOX_DARK_HARD_H
|
||||||
|
#define GRUVBOX_DARK_HARD_H
|
||||||
|
|
||||||
|
static const char norm_fg[] = "#D5C4A1"; // light2
|
||||||
|
static const char norm_bg[] = "#1D2021"; // dark0_hard
|
||||||
|
static const char norm_border[] = "#504945"; // dark2
|
||||||
|
|
||||||
|
static const char sel_fg[] = "#D79921"; // neutral_yellow
|
||||||
|
static const char sel_bg[] = "#1D2021"; // dark0_hard
|
||||||
|
static const char sel_border[] = "#7C6F64"; // dark4
|
||||||
|
|
||||||
|
static const char urg_fg[] = "#D5C4A1"; // light4
|
||||||
|
static const char urg_bg[] = "#FB4934"; // bright_red
|
||||||
|
static const char urg_border[] = "#458588"; // neutral_blue
|
||||||
|
|
||||||
|
static const char *colors[][3] = {
|
||||||
|
/* fg bg border */
|
||||||
|
[SchemeNorm] = {norm_fg, norm_bg, norm_border}, // unfocused wins
|
||||||
|
[SchemeSel] = {sel_fg, sel_bg, sel_border}, // the focused win
|
||||||
|
[SchemeUrg] = {urg_fg, urg_bg, urg_border},
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //GRUVBOX_DARK_HARD_H
|
|
@ -1,68 +0,0 @@
|
||||||
/* See LICENSE file for copyright and license details. */
|
|
||||||
|
|
||||||
/* def */
|
|
||||||
#define WEBBROWSER "google-chrome-stable"
|
|
||||||
#define TERMINAL "alacritty"
|
|
||||||
#define SCREENSHOT "spectacle"
|
|
||||||
#define GUI_FILEMANAGER "pcmanfm"
|
|
||||||
|
|
||||||
/* appearance */
|
|
||||||
static const unsigned int borderpx = 1; /* border pixel of windows */
|
|
||||||
static const unsigned int gappx = 3; /* gaps size between windows */
|
|
||||||
static const unsigned int snap = 32; /* snap pixel */
|
|
||||||
static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */
|
|
||||||
static const unsigned int systrayonleft = 0; /* 0: systray in the right corner, >0: systray on left of status text */
|
|
||||||
static const unsigned int systrayspacing = 2; /* systray spacing */
|
|
||||||
static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/
|
|
||||||
static const int showsystray = 1; /* 0 means no systray */
|
|
||||||
static const int showbar = 1; /* 0 means no bar */
|
|
||||||
static const int topbar = 1; /* 0 means bottom bar */
|
|
||||||
static const char *fonts[] = { "monospace:size=11", "Noto Color Emoji:size=11", "Nerd Font Mono:weight=bold:size=15:antialias=true:hinting=true" };
|
|
||||||
static const char dmenufont[] = "monospace:size=11";
|
|
||||||
static const char col_1[] = "#282c34"; // Background color of bar
|
|
||||||
static const char col_2[] = "#282c34"; // Background color of unfocused windows border
|
|
||||||
static const char col_3[] = "#d7d7d7";
|
|
||||||
static const char col_4[] = "#018858"; // Background color of focused windows border and tags (main color acent)
|
|
||||||
static const char *colors[][3] = {
|
|
||||||
/* fg bg border */
|
|
||||||
[SchemeNorm] = { col_3, col_1, col_2 },
|
|
||||||
[SchemeSel] = { col_3, col_4, col_4 },
|
|
||||||
};
|
|
||||||
// Autostart programs
|
|
||||||
static const char *const autostart[] = {
|
|
||||||
// Start my build of slstatus
|
|
||||||
"slstatus", NULL,
|
|
||||||
// Keyboard layouts switch (requires setxkbmap)
|
|
||||||
"setxkbmap", "-model", "pc101", "-layout", "us,ar", "-variant", ",,", "-option", "grp:win_space_toggle", NULL,
|
|
||||||
// "xkbset", "exp", "=sticky", "-twokey", "-latchlock", NULL, // sticky keys
|
|
||||||
"/bin/stickykeys", NULL, // sticky keys script
|
|
||||||
"picom", NULL, // Start compositor , for transparency
|
|
||||||
"nitrogen", "--restore", NULL, // Restores the wallpaper
|
|
||||||
"nm-applet", NULL, // Start the network manger
|
|
||||||
"copyq", NULL, // clipboard manger
|
|
||||||
NULL /* terminate */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* tagging */
|
|
||||||
// static const char *tags[] = { "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX" };
|
|
||||||
static const char *tags[] = { "", "", "", "", "", "", "", "", "" };
|
|
||||||
|
|
||||||
static const Rule rules[] = {
|
|
||||||
/* xprop(1):
|
|
||||||
* WM_CLASS(STRING) = instance, class
|
|
||||||
* WM_NAME(STRING) = title
|
|
||||||
*/
|
|
||||||
/* class instance title tags mask isfloating monitor */
|
|
||||||
{ "Gimp", NULL, NULL, 0, 1, -1 },
|
|
||||||
{ WEBBROWSER, NULL, NULL, 1 << 8, 0, -1 },
|
|
||||||
};
|
|
||||||
|
|
||||||
/* layout(s) */
|
|
||||||
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
|
|
||||||
static const int nmaster = 1; /* number of clients in master area */
|
|
||||||
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
|
|
||||||
static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
|
|
||||||
|
|
||||||
#include "layouts/layouts.h"
|
|
||||||
#include "movestack.c"
|
|
||||||
#include "keys/keys.h"
|
|
63
src/config.h
63
src/config.h
|
@ -1,63 +0,0 @@
|
||||||
/* See LICENSE file for copyright and license details. */
|
|
||||||
|
|
||||||
/* def */
|
|
||||||
#define WEBBROWSER "google-chrome-stable"
|
|
||||||
#define TERMINAL "alacritty"
|
|
||||||
#define SCREENSHOT "spectacle"
|
|
||||||
#define GUI_FILEMANAGER "pcmanfm"
|
|
||||||
|
|
||||||
/* appearance */
|
|
||||||
static const unsigned int borderpx = 1; /* border pixel of windows */
|
|
||||||
static const unsigned int gappx = 3; /* gaps size between windows */
|
|
||||||
static const unsigned int snap = 32; /* snap pixel */
|
|
||||||
static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */
|
|
||||||
static const unsigned int systrayonleft = 0; /* 0: systray in the right corner, >0: systray on left of status text */
|
|
||||||
static const unsigned int systrayspacing = 2; /* systray spacing */
|
|
||||||
static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/
|
|
||||||
static const int showsystray = 1; /* 0 means no systray */
|
|
||||||
static const int showbar = 1; /* 0 means no bar */
|
|
||||||
static const int topbar = 0; /* 0 means bottom bar */
|
|
||||||
static const char *fonts[] = { "monospace:size=7", "Noto Color Emoji:size=8", "Nerd Font Mono:size=16:antialias=true:hinting=true" };
|
|
||||||
static const char dmenufont[] = "monospace:size=8";
|
|
||||||
|
|
||||||
#include "colors.h"
|
|
||||||
|
|
||||||
// Autostart programs
|
|
||||||
static const char *const autostart[] = {
|
|
||||||
// Start my build of slstatus
|
|
||||||
"slstatus", NULL,
|
|
||||||
// Keyboard layouts switch (requires setxkbmap)
|
|
||||||
"setxkbmap", "-model", "pc101", "-layout", "us,ar", "-variant", ",,", "-option", "grp:win_space_toggle", NULL,
|
|
||||||
// "xkbset", "exp", "=sticky", "-twokey", "-latchlock", NULL, // sticky keys
|
|
||||||
"/bin/stickykeys", NULL, // sticky keys script
|
|
||||||
"picom", NULL, // Start compositor , for transparency
|
|
||||||
"nitrogen", "--restore", NULL, // Restores the wallpaper
|
|
||||||
"nm-applet", NULL, // Start the network manger
|
|
||||||
"copyq", NULL, // clipboard manger
|
|
||||||
NULL /* terminate */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* tagging */
|
|
||||||
// static const char *tags[] = { "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX" };
|
|
||||||
// static const char *tags[] = { "", "", "", "", "", "", "", "", "" };
|
|
||||||
static const char *tags[] = { "www", "dev", "sys", "chat", "img", "vid", "mus", "vbox", "gfx", ";" };
|
|
||||||
|
|
||||||
static const Rule rules[] = {
|
|
||||||
/* xprop(1):
|
|
||||||
* WM_CLASS(STRING) = instance, class
|
|
||||||
* WM_NAME(STRING) = title
|
|
||||||
*/
|
|
||||||
/* class instance title tags mask isfloating monitor */
|
|
||||||
{ "Gimp", NULL, NULL, 0, 1, -1 },
|
|
||||||
{ WEBBROWSER, NULL, NULL, 1 << 8, 0, -1 },
|
|
||||||
};
|
|
||||||
|
|
||||||
/* layout(s) */
|
|
||||||
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
|
|
||||||
static const int nmaster = 1; /* number of clients in master area */
|
|
||||||
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
|
|
||||||
static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
|
|
||||||
|
|
||||||
#include "layouts/layouts.h"
|
|
||||||
#include "movestack.c"
|
|
||||||
#include "keys/keys.h"
|
|
100
src/config/config.h
Normal file
100
src/config/config.h
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
#ifndef CONFIG_H
|
||||||
|
#define CONFIG_H
|
||||||
|
/* def */
|
||||||
|
#define TERMINAL "st"
|
||||||
|
|
||||||
|
#ifndef STDDEF_H
|
||||||
|
#include <stddef.h>
|
||||||
|
#endif
|
||||||
|
#ifndef ARCHY_DWM_H
|
||||||
|
#include "../archy_dwm.h"
|
||||||
|
#endif
|
||||||
|
#include "keys.h"
|
||||||
|
#include "mouse.h"
|
||||||
|
|
||||||
|
/* appearance */
|
||||||
|
static const unsigned int borderpx = 1; /* border pixel of windows */
|
||||||
|
static const unsigned int gappx = 3; /* gaps size between windows */
|
||||||
|
static const unsigned int snap = 32; /* snap pixel */
|
||||||
|
static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */
|
||||||
|
static const unsigned int systrayonleft = -1; /* 0: systray in the right corner, >0: systray on left of status text */
|
||||||
|
static const unsigned int systrayspacing = 2; /* systray spacing */
|
||||||
|
static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/
|
||||||
|
static const int showsystray = 1; /* 0 means no systray */
|
||||||
|
static const int showbar = 1; /* 0 means no bar */
|
||||||
|
static const int topbar = 0; /* 0 means bottom bar */
|
||||||
|
static const char *fonts[] = {
|
||||||
|
"monospace:size=6", "Noto Color Emoji:size=7",
|
||||||
|
"Nerd Font Mono:size=10:antialias=true:hinting=true"};
|
||||||
|
static const char dmenufont[] = "monospace:size=8";
|
||||||
|
|
||||||
|
/* Colors - Gruvbox dark hard */
|
||||||
|
static const char norm_fg[] = "#D5C4A1"; // light2
|
||||||
|
static const char norm_bg[] = "#1D2021"; // dark0_hard
|
||||||
|
static const char norm_border[] = "#504945"; // dark2
|
||||||
|
|
||||||
|
static const char sel_fg[] = "#D79921"; // neutral_yellow
|
||||||
|
static const char sel_bg[] = "#1D2021"; // dark0_hard
|
||||||
|
static const char sel_border[] = "#7C6F64"; // dark4
|
||||||
|
|
||||||
|
static const char urg_fg[] = "#D5C4A1"; // light4
|
||||||
|
static const char urg_bg[] = "#FB4934"; // bright_red
|
||||||
|
static const char urg_border[] = "#458588"; // neutral_blue
|
||||||
|
|
||||||
|
static const char *colors[][3] = {
|
||||||
|
/* fg bg border */
|
||||||
|
[SchemeNorm] = {norm_fg, norm_bg, norm_border}, // unfocused wins
|
||||||
|
[SchemeSel] = {sel_fg, sel_bg, sel_border}, // the focused win
|
||||||
|
[SchemeUrg] = {urg_fg, urg_bg, urg_border},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Autostart programs
|
||||||
|
static const char *const autostart[] = {
|
||||||
|
// Start my build of slstatus
|
||||||
|
"archy-slstatus", NULL,
|
||||||
|
NULL /* terminate */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* tagging */
|
||||||
|
// static const char *tags[] = { "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX" };
|
||||||
|
// static const char *tags[] = { "", "", "", "", "", "", "", "", "" };
|
||||||
|
static const char *tags[] = {"www", "dev", "sys", "chat", "lab", "vid", "mus", "vbox", "gfx", ";"};
|
||||||
|
|
||||||
|
static const Rule rules[] = {
|
||||||
|
/* xprop(1):
|
||||||
|
* WM_CLASS(STRING) = instance, class
|
||||||
|
* WM_NAME(STRING) = title
|
||||||
|
* It's just a bitwise shift. Binary of 5 is 101, then you shift it left on
|
||||||
|
*6 and get 101000000, which means 7 and 9 in dwm ( because 1-s are on 7 and
|
||||||
|
*9 position from right).
|
||||||
|
* https://www.reddit.com/r/dwm/comments/f2omo9/comment/fjr93yt/?utm_source=share&utm_medium=web2x&context=3
|
||||||
|
*/
|
||||||
|
/* class instance title tags mask isfloating monitor */
|
||||||
|
{"Gimp", NULL, NULL, 9 << 8, 1, -1}, // 0100000000 (gfx tag)
|
||||||
|
{"Tor Browser", "Navigator", NULL, 9 << 9, 0,-1}, // Open it in tag 10 (9 in array) (; tag)
|
||||||
|
{"KeePassXC", "keepassxc", NULL, 9 << 9, 0, -1}, // 1000000000 (; tag)
|
||||||
|
{"firefoxdeveloperedition", "Navigator", NULL, 1 << 0, 0,-1}, // 0000000001 (www tag)
|
||||||
|
//{"discord", NULL, NULL, 4 << 1, 0, -1}, // 0000001000 (chat tag)
|
||||||
|
{"Virt-manager", "virt-manager", NULL, 9 << 7, 0,-1}, // 0010000000 (vbox tag)
|
||||||
|
{"VirtualBox Manager", "VirtualBox Manager", NULL, 9 << 7, 0,1}, // 0010000000 (vbox tag)
|
||||||
|
{NULL, "open.spotify.com", NULL, 8 << 3, 0, -1}, // 0001000000 (mus tag)
|
||||||
|
{"cmus", NULL, NULL, 8 << 3, 0, -1}, // 0001000000 (mus tag)
|
||||||
|
{"jetbrains-clion", NULL, NULL, 1 << 1, 0, -1}, // 0000000010 (dev tag)
|
||||||
|
{"jetbrains-idea", NULL, NULL, 1 << 1, 0, -1}, // 0000000010 (dev tag)
|
||||||
|
{"jetbrains-pycharm", NULL, NULL, 1 << 1, 0, -1}, // 0000000010 (dev tag)
|
||||||
|
{"jetbrains-studio", NULL, NULL, 1 << 1, 0, -1}, // 0000000010 (dev tag)
|
||||||
|
{"jetbrains-webstorm", NULL, NULL, 1 << 1, 0, -1}, // 0000000010 (dev tag)
|
||||||
|
{"jetbrains-phpstorm", NULL, NULL, 1 << 1, 0, -1}, // 0000000010 (dev tag)
|
||||||
|
{"jetbrains-rubymine", NULL, NULL, 1 << 1, 0, -1}, // 0000000010 (dev tag)
|
||||||
|
{"jetbrains-goland", NULL, NULL, 1 << 1, 0, -1}, // 0000000010 (dev tag)
|
||||||
|
{"jetbrains-datagrip", NULL, NULL, 1 << 1, 0, -1}, // 0000000010 (dev tag)
|
||||||
|
{"PacketTracer", NULL, NULL, 1 << 4, 0, -1} // 0000010000 (lab tag)
|
||||||
|
};
|
||||||
|
|
||||||
|
/* layout(s) */
|
||||||
|
static const float mfact = 0.60f; /* factor of master area size [0.05..0.95] */
|
||||||
|
static const int nmaster = 1; /* number of clients in master area */
|
||||||
|
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
|
||||||
|
static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
|
||||||
|
|
||||||
|
#endif // CONFIG_H
|
97
src/config/keys.h
Normal file
97
src/config/keys.h
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
#ifndef KEYS_H
|
||||||
|
#define KEYS_H
|
||||||
|
|
||||||
|
#include "../archy_dwm.h"
|
||||||
|
#include <X11/X.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int mod;
|
||||||
|
KeySym keysym;
|
||||||
|
|
||||||
|
void (*func)(const Arg *);
|
||||||
|
|
||||||
|
const Arg arg;
|
||||||
|
} Key;
|
||||||
|
|
||||||
|
/* key definitions */
|
||||||
|
#define MODKEY Mod4Mask // The super key
|
||||||
|
|
||||||
|
#define TAGKEYS(KEY, TAG) \
|
||||||
|
{MODKEY, KEY, view, {.ui = 1 << TAG}}, \
|
||||||
|
{MODKEY | ControlMask, KEY, toggleview, {.ui = 1 << TAG}}, \
|
||||||
|
{MODKEY | ShiftMask, KEY, tag, {.ui = 1 << TAG}}, \
|
||||||
|
{MODKEY | ControlMask | ShiftMask, KEY, toggletag, {.ui = 1 << TAG}},
|
||||||
|
|
||||||
|
#ifndef ACTIONS_H
|
||||||
|
#include "../actions.h"
|
||||||
|
#endif //ACTIONS_H
|
||||||
|
#ifndef LAYOUTS_H
|
||||||
|
#include "../layouts/layouts.h"
|
||||||
|
#endif //LAYOUTS_H
|
||||||
|
// X11 keysym definitions
|
||||||
|
#include <X11/XF86keysym.h> // req (libxinerama1 and libxinerama-dev)
|
||||||
|
|
||||||
|
#include <X11/keysym.h>
|
||||||
|
|
||||||
|
static Key keys[] = {
|
||||||
|
/* modifier key function argument */
|
||||||
|
{MODKEY, XK_f, fullscreen, {0}},
|
||||||
|
{MODKEY|ShiftMask, XK_b, togglebar, {0}},
|
||||||
|
// Change the focus
|
||||||
|
{MODKEY, XK_e, focusstack, {.i = +1}},
|
||||||
|
{MODKEY, XK_a, focusstack, {.i = -1}},
|
||||||
|
// incress and decrees the masters
|
||||||
|
{MODKEY, XK_i, incnmaster, {.i = +1}},
|
||||||
|
{MODKEY, XK_d, incnmaster, {.i = -1}},
|
||||||
|
// Change the focus window size (in the tile mode)
|
||||||
|
{MODKEY, XK_equal, setmfact, {.f = -0.05f}},
|
||||||
|
{MODKEY, XK_minus, setmfact, {.f = +0.05f}},
|
||||||
|
{MODKEY, XK_Tab, view, {0}},
|
||||||
|
{MODKEY | ShiftMask, XK_e, movestack, {.i = +1}},
|
||||||
|
{MODKEY | ShiftMask, XK_a, movestack, {.i = -1}},
|
||||||
|
// Toogle styky mode
|
||||||
|
{MODKEY | ShiftMask, XK_s, togglesticky, {0}},
|
||||||
|
// Quit from the foucsed window (kill)
|
||||||
|
{MODKEY|ShiftMask, XK_q, killclient, {0}},
|
||||||
|
/************************* Switch between layouts *************************/
|
||||||
|
// Tiled layout
|
||||||
|
{MODKEY, XK_t, setlayout, {.v = &layouts[0]}},
|
||||||
|
// Floating layout
|
||||||
|
{MODKEY, XK_f, setlayout, {.v = &layouts[1]}},
|
||||||
|
// Monocle layout
|
||||||
|
{MODKEY, XK_m, setlayout, {.v = &layouts[2]}},
|
||||||
|
// Grid layout
|
||||||
|
{MODKEY, XK_g, setlayout, {.v = &layouts[3]}},
|
||||||
|
// Spiral layout
|
||||||
|
{MODKEY, XK_r, setlayout, {.v = &layouts[4]}},
|
||||||
|
// Dwindle layout
|
||||||
|
{MODKEY, XK_d, setlayout, {.v = &layouts[5]}},
|
||||||
|
// Centerd master layout
|
||||||
|
{MODKEY, XK_c, setlayout, {.v = &layouts[6]}},
|
||||||
|
// Centerd floating master layout
|
||||||
|
{MODKEY, XK_x, setlayout, {.v = &layouts[7]}},
|
||||||
|
// Toggle between current layout and tile layout
|
||||||
|
{MODKEY, XK_s, setlayout, {0}},
|
||||||
|
// Toggle floating window
|
||||||
|
{MODKEY | ShiftMask, XK_f, togglefloating, {0}},
|
||||||
|
// Mirror the current tagg in all tags
|
||||||
|
{MODKEY, XK_0, tag, {.ui = ~0}},
|
||||||
|
// Multi monitor stuff
|
||||||
|
{MODKEY, XK_comma, focusmon, {.i = -1}},
|
||||||
|
{MODKEY, XK_period, focusmon, {.i = +1}},
|
||||||
|
{MODKEY | ShiftMask, XK_comma, tagmon, {.i = -1}},
|
||||||
|
{MODKEY | ShiftMask, XK_period, tagmon, {.i = +1}},
|
||||||
|
/************************* Tag keys *************************/
|
||||||
|
TAGKEYS(XK_1, 0)
|
||||||
|
TAGKEYS(XK_2, 1)
|
||||||
|
TAGKEYS(XK_3, 2)
|
||||||
|
TAGKEYS(XK_4, 3)
|
||||||
|
TAGKEYS(XK_5, 4)
|
||||||
|
TAGKEYS(XK_6, 5)
|
||||||
|
TAGKEYS(XK_7, 6)
|
||||||
|
TAGKEYS(XK_8, 7)
|
||||||
|
TAGKEYS(XK_9, 8)
|
||||||
|
TAGKEYS(XK_semicolon, 9)
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // keys_H
|
40
src/config/mouse.h
Normal file
40
src/config/mouse.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
//
|
||||||
|
// Created by anas on 10/31/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef MOUSE_H
|
||||||
|
#define MOUSE_H
|
||||||
|
|
||||||
|
#include <X11/X.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int click;
|
||||||
|
unsigned int mask;
|
||||||
|
unsigned int button;
|
||||||
|
|
||||||
|
void (*func)(const Arg *arg);
|
||||||
|
|
||||||
|
const Arg arg;
|
||||||
|
} Button;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
|
||||||
|
ClkClientWin, ClkRootWin, ClkLast
|
||||||
|
}; /* clicks */
|
||||||
|
|
||||||
|
/* button definitions */
|
||||||
|
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
|
||||||
|
static Button buttons[] = {
|
||||||
|
/* click event mask button function argument */
|
||||||
|
{ClkTagBar, MODKEY, Button1, tag, {0}},
|
||||||
|
{ClkTagBar, MODKEY, Button3, toggletag, {0}},
|
||||||
|
{ClkClientWin, MODKEY, Button1, movemouse, {0}},
|
||||||
|
{ClkClientWin, MODKEY, Button2, togglefloating, {0}},
|
||||||
|
{ClkClientWin, MODKEY, Button3, resizemouse, {0}},
|
||||||
|
{ClkTagBar, 0, Button1, view, {0}},
|
||||||
|
{ClkTagBar, 0, Button3, toggleview, {0}},
|
||||||
|
{ClkTagBar, MODKEY, Button1, tag, {0}},
|
||||||
|
{ClkTagBar, MODKEY, Button3, toggletag, {0}},
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //MOUSE_H
|
642
src/drw.c
642
src/drw.c
|
@ -11,441 +11,421 @@
|
||||||
#define UTF_INVALID 0xFFFD
|
#define UTF_INVALID 0xFFFD
|
||||||
#define UTF_SIZ 4
|
#define UTF_SIZ 4
|
||||||
|
|
||||||
static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
|
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 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 utfmin[UTF_SIZ + 1] = {0, 0, 0x80, 0x800, 0x10000};
|
||||||
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
|
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
|
||||||
|
|
||||||
static long
|
static long
|
||||||
utf8decodebyte(const char c, size_t *i)
|
utf8decodebyte(const char c, size_t *i) {
|
||||||
{
|
for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
|
||||||
for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
|
if (((unsigned char) c & utfmask[*i]) == utfbyte[*i])
|
||||||
if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
|
return (unsigned char) c & ~utfmask[*i];
|
||||||
return (unsigned char)c & ~utfmask[*i];
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
utf8validate(long *u, size_t i)
|
utf8validate(long *u, size_t i) {
|
||||||
{
|
if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
|
||||||
if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
|
*u = UTF_INVALID;
|
||||||
*u = UTF_INVALID;
|
for (i = 1; *u > utfmax[i]; ++i);
|
||||||
for (i = 1; *u > utfmax[i]; ++i)
|
return i;
|
||||||
;
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
utf8decode(const char *c, long *u, size_t clen)
|
utf8decode(const char *c, long *u, size_t clen) {
|
||||||
{
|
size_t i, j, len, type;
|
||||||
size_t i, j, len, type;
|
long udecoded;
|
||||||
long udecoded;
|
|
||||||
|
|
||||||
*u = UTF_INVALID;
|
*u = UTF_INVALID;
|
||||||
if (!clen)
|
if (!clen)
|
||||||
return 0;
|
return 0;
|
||||||
udecoded = utf8decodebyte(c[0], &len);
|
udecoded = utf8decodebyte(c[0], &len);
|
||||||
if (!BETWEEN(len, 1, UTF_SIZ))
|
if (!BETWEEN(len, 1, UTF_SIZ))
|
||||||
return 1;
|
return 1;
|
||||||
for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
|
for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
|
||||||
udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
|
udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
|
||||||
if (type)
|
if (type)
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
if (j < len)
|
if (j < len)
|
||||||
return 0;
|
return 0;
|
||||||
*u = udecoded;
|
*u = udecoded;
|
||||||
utf8validate(u, len);
|
utf8validate(u, len);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
Drw *
|
Drw *
|
||||||
drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
|
drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) {
|
||||||
{
|
Drw *drw = ecalloc(1, sizeof(Drw));
|
||||||
Drw *drw = ecalloc(1, sizeof(Drw));
|
|
||||||
|
|
||||||
drw->dpy = dpy;
|
drw->dpy = dpy;
|
||||||
drw->screen = screen;
|
drw->screen = screen;
|
||||||
drw->root = root;
|
drw->root = root;
|
||||||
drw->w = w;
|
drw->w = w;
|
||||||
drw->h = h;
|
drw->h = h;
|
||||||
drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
|
drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
|
||||||
drw->gc = XCreateGC(dpy, root, 0, NULL);
|
drw->gc = XCreateGC(dpy, root, 0, NULL);
|
||||||
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
|
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||||
|
|
||||||
return drw;
|
return drw;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
drw_resize(Drw *drw, unsigned int w, unsigned int h)
|
drw_resize(Drw *drw, unsigned int w, unsigned int h) {
|
||||||
{
|
if (!drw)
|
||||||
if (!drw)
|
return;
|
||||||
return;
|
|
||||||
|
|
||||||
drw->w = w;
|
drw->w = w;
|
||||||
drw->h = h;
|
drw->h = h;
|
||||||
if (drw->drawable)
|
if (drw->drawable)
|
||||||
XFreePixmap(drw->dpy, drw->drawable);
|
XFreePixmap(drw->dpy, drw->drawable);
|
||||||
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
|
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
drw_free(Drw *drw)
|
drw_free(Drw *drw) {
|
||||||
{
|
XFreePixmap(drw->dpy, drw->drawable);
|
||||||
XFreePixmap(drw->dpy, drw->drawable);
|
XFreeGC(drw->dpy, drw->gc);
|
||||||
XFreeGC(drw->dpy, drw->gc);
|
drw_fontset_free(drw->fonts);
|
||||||
drw_fontset_free(drw->fonts);
|
free(drw);
|
||||||
free(drw);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is an implementation detail. Library users should use
|
/* This function is an implementation detail. Library users should use
|
||||||
* drw_fontset_create instead.
|
* drw_fontset_create instead.
|
||||||
*/
|
*/
|
||||||
static Fnt *
|
static Fnt *
|
||||||
xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
|
xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) {
|
||||||
{
|
Fnt *font;
|
||||||
Fnt *font;
|
XftFont *xfont = NULL;
|
||||||
XftFont *xfont = NULL;
|
FcPattern *pattern = NULL;
|
||||||
FcPattern *pattern = NULL;
|
|
||||||
|
|
||||||
if (fontname) {
|
if (fontname) {
|
||||||
/* Using the pattern found at font->xfont->pattern does not yield the
|
/* Using the pattern found at font->xfont->pattern does not yield the
|
||||||
* same substitution results as using the pattern returned by
|
* same substitution results as using the pattern returned by
|
||||||
* FcNameParse; using the latter results in the desired fallback
|
* FcNameParse; using the latter results in the desired fallback
|
||||||
* behaviour whereas the former just results in missing-character
|
* behaviour whereas the former just results in missing-character
|
||||||
* rectangles being drawn, at least with some fonts. */
|
* rectangles being drawn, at least with some fonts. */
|
||||||
if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
|
if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
|
||||||
fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
|
fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
|
if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
|
||||||
fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
|
fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
|
||||||
XftFontClose(drw->dpy, xfont);
|
XftFontClose(drw->dpy, xfont);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else if (fontpattern) {
|
} else if (fontpattern) {
|
||||||
if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
|
if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
|
||||||
fprintf(stderr, "error, cannot load font from pattern.\n");
|
fprintf(stderr, "error, cannot load font from pattern.\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
die("no font specified.");
|
die("no font specified.");
|
||||||
}
|
}
|
||||||
|
|
||||||
font = ecalloc(1, sizeof(Fnt));
|
font = ecalloc(1, sizeof(Fnt));
|
||||||
font->xfont = xfont;
|
font->xfont = xfont;
|
||||||
font->pattern = pattern;
|
font->pattern = pattern;
|
||||||
font->h = xfont->ascent + xfont->descent;
|
font->h = xfont->ascent + xfont->descent;
|
||||||
font->dpy = drw->dpy;
|
font->dpy = drw->dpy;
|
||||||
|
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xfont_free(Fnt *font)
|
xfont_free(Fnt *font) {
|
||||||
{
|
if (!font)
|
||||||
if (!font)
|
return;
|
||||||
return;
|
if (font->pattern)
|
||||||
if (font->pattern)
|
FcPatternDestroy(font->pattern);
|
||||||
FcPatternDestroy(font->pattern);
|
XftFontClose(font->dpy, font->xfont);
|
||||||
XftFontClose(font->dpy, font->xfont);
|
free(font);
|
||||||
free(font);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Fnt*
|
Fnt *
|
||||||
drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
|
drw_fontset_create(Drw *drw, const char *fonts[], size_t fontcount) {
|
||||||
{
|
Fnt *cur, *ret = NULL;
|
||||||
Fnt *cur, *ret = NULL;
|
size_t i;
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (!drw || !fonts)
|
if (!drw || !fonts)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (i = 1; i <= fontcount; i++) {
|
for (i = 1; i <= fontcount; i++) {
|
||||||
if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
|
if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
|
||||||
cur->next = ret;
|
cur->next = ret;
|
||||||
ret = cur;
|
ret = cur;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (drw->fonts = ret);
|
return (drw->fonts = ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
drw_fontset_free(Fnt *font)
|
drw_fontset_free(Fnt *font) {
|
||||||
{
|
if (font) {
|
||||||
if (font) {
|
drw_fontset_free(font->next);
|
||||||
drw_fontset_free(font->next);
|
xfont_free(font);
|
||||||
xfont_free(font);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
|
drw_clr_create(Drw *drw, Clr *dest, const char *clrname) {
|
||||||
{
|
if (!drw || !dest || !clrname)
|
||||||
if (!drw || !dest || !clrname)
|
return;
|
||||||
return;
|
|
||||||
|
|
||||||
if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
|
if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
|
||||||
DefaultColormap(drw->dpy, drw->screen),
|
DefaultColormap(drw->dpy, drw->screen),
|
||||||
clrname, dest))
|
clrname, dest))
|
||||||
die("error, cannot allocate color '%s'", clrname);
|
die("error, cannot allocate color '%s'", clrname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wrapper to create color schemes. The caller has to call free(3) on the
|
/* Wrapper to create color schemes. The caller has to call free(3) on the
|
||||||
* returned color scheme when done using it. */
|
* returned color scheme when done using it. */
|
||||||
Clr *
|
Clr *
|
||||||
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
|
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) {
|
||||||
{
|
size_t i;
|
||||||
size_t i;
|
Clr *ret;
|
||||||
Clr *ret;
|
|
||||||
|
|
||||||
/* need at least two colors for a scheme */
|
/* need at least two colors for a scheme */
|
||||||
if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
|
if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (i = 0; i < clrcount; i++)
|
for (i = 0; i < clrcount; i++)
|
||||||
drw_clr_create(drw, &ret[i], clrnames[i]);
|
drw_clr_create(drw, &ret[i], clrnames[i]);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
drw_setfontset(Drw *drw, Fnt *set)
|
drw_setfontset(Drw *drw, Fnt *set) {
|
||||||
{
|
if (drw)
|
||||||
if (drw)
|
drw->fonts = set;
|
||||||
drw->fonts = set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
drw_setscheme(Drw *drw, Clr *scm)
|
drw_setscheme(Drw *drw, Clr *scm) {
|
||||||
{
|
if (drw)
|
||||||
if (drw)
|
drw->scheme = scm;
|
||||||
drw->scheme = scm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
|
drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert) {
|
||||||
{
|
if (!drw || !drw->scheme)
|
||||||
if (!drw || !drw->scheme)
|
return;
|
||||||
return;
|
XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
|
||||||
XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
|
if (filled)
|
||||||
if (filled)
|
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
||||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
else
|
||||||
else
|
XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
|
||||||
XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
|
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) {
|
||||||
{
|
int i, ty, ellipsis_x = 0;
|
||||||
int i, ty, ellipsis_x = 0;
|
unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len;
|
||||||
unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len;
|
XftDraw *d = NULL;
|
||||||
XftDraw *d = NULL;
|
Fnt *usedfont, *curfont, *nextfont;
|
||||||
Fnt *usedfont, *curfont, *nextfont;
|
int utf8strlen, utf8charlen, render = x || y || w || h;
|
||||||
int utf8strlen, utf8charlen, render = x || y || w || h;
|
long utf8codepoint = 0;
|
||||||
long utf8codepoint = 0;
|
const char *utf8str;
|
||||||
const char *utf8str;
|
FcCharSet *fccharset;
|
||||||
FcCharSet *fccharset;
|
FcPattern *fcpattern;
|
||||||
FcPattern *fcpattern;
|
FcPattern *match;
|
||||||
FcPattern *match;
|
XftResult result;
|
||||||
XftResult result;
|
int charexists = 0, overflow = 0;
|
||||||
int charexists = 0, overflow = 0;
|
/* keep track of a couple codepoints for which we have no match. */
|
||||||
/* keep track of a couple codepoints for which we have no match. */
|
enum {
|
||||||
enum { nomatches_len = 64 };
|
nomatches_len = 64
|
||||||
static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches;
|
};
|
||||||
static unsigned int ellipsis_width = 0;
|
static struct {
|
||||||
|
long codepoint[nomatches_len];
|
||||||
|
unsigned int idx;
|
||||||
|
} nomatches;
|
||||||
|
static unsigned int ellipsis_width = 0;
|
||||||
|
|
||||||
if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
|
if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!render) {
|
if (!render) {
|
||||||
w = invert ? invert : ~invert;
|
w = invert ? invert : ~invert;
|
||||||
} else {
|
} else {
|
||||||
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
|
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
|
||||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
||||||
d = XftDrawCreate(drw->dpy, drw->drawable,
|
d = XftDrawCreate(drw->dpy, drw->drawable,
|
||||||
DefaultVisual(drw->dpy, drw->screen),
|
DefaultVisual(drw->dpy, drw->screen),
|
||||||
DefaultColormap(drw->dpy, drw->screen));
|
DefaultColormap(drw->dpy, drw->screen));
|
||||||
x += lpad;
|
x += lpad;
|
||||||
w -= lpad;
|
w -= lpad;
|
||||||
}
|
}
|
||||||
|
|
||||||
usedfont = drw->fonts;
|
usedfont = drw->fonts;
|
||||||
if (!ellipsis_width && render)
|
if (!ellipsis_width && render)
|
||||||
ellipsis_width = drw_fontset_getwidth(drw, "...");
|
ellipsis_width = drw_fontset_getwidth(drw, "...");
|
||||||
while (1) {
|
while (1) {
|
||||||
ew = ellipsis_len = utf8strlen = 0;
|
ew = ellipsis_len = utf8strlen = 0;
|
||||||
utf8str = text;
|
utf8str = text;
|
||||||
nextfont = NULL;
|
nextfont = NULL;
|
||||||
while (*text) {
|
while (*text) {
|
||||||
utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
|
utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
|
||||||
for (curfont = drw->fonts; curfont; curfont = curfont->next) {
|
for (curfont = drw->fonts; curfont; curfont = curfont->next) {
|
||||||
charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
|
charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
|
||||||
if (charexists) {
|
if (charexists) {
|
||||||
drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL);
|
drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL);
|
||||||
if (ew + ellipsis_width <= w) {
|
if (ew + ellipsis_width <= w) {
|
||||||
/* keep track where the ellipsis still fits */
|
/* keep track where the ellipsis still fits */
|
||||||
ellipsis_x = x + ew;
|
ellipsis_x = x + ew;
|
||||||
ellipsis_w = w - ew;
|
ellipsis_w = w - ew;
|
||||||
ellipsis_len = utf8strlen;
|
ellipsis_len = utf8strlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ew + tmpw > w) {
|
if (ew + tmpw > w) {
|
||||||
overflow = 1;
|
overflow = 1;
|
||||||
/* called from drw_fontset_getwidth_clamp():
|
/* called from drw_fontset_getwidth_clamp():
|
||||||
* it wants the width AFTER the overflow
|
* it wants the width AFTER the overflow
|
||||||
*/
|
*/
|
||||||
if (!render)
|
if (!render)
|
||||||
x += tmpw;
|
x += tmpw;
|
||||||
else
|
else
|
||||||
utf8strlen = ellipsis_len;
|
utf8strlen = ellipsis_len;
|
||||||
} else if (curfont == usedfont) {
|
} else if (curfont == usedfont) {
|
||||||
utf8strlen += utf8charlen;
|
utf8strlen += utf8charlen;
|
||||||
text += utf8charlen;
|
text += utf8charlen;
|
||||||
ew += tmpw;
|
ew += tmpw;
|
||||||
} else {
|
} else {
|
||||||
nextfont = curfont;
|
nextfont = curfont;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overflow || !charexists || nextfont)
|
if (overflow || !charexists || nextfont)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
charexists = 0;
|
charexists = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (utf8strlen) {
|
if (utf8strlen) {
|
||||||
if (render) {
|
if (render) {
|
||||||
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
|
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
|
||||||
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
|
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
|
||||||
usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen);
|
usedfont->xfont, x, ty, (XftChar8 *) utf8str, utf8strlen);
|
||||||
}
|
}
|
||||||
x += ew;
|
x += ew;
|
||||||
w -= ew;
|
w -= ew;
|
||||||
}
|
}
|
||||||
if (render && overflow)
|
if (render && overflow)
|
||||||
drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert);
|
drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert);
|
||||||
|
|
||||||
if (!*text || overflow) {
|
if (!*text || overflow) {
|
||||||
break;
|
break;
|
||||||
} else if (nextfont) {
|
} else if (nextfont) {
|
||||||
charexists = 0;
|
charexists = 0;
|
||||||
usedfont = nextfont;
|
usedfont = nextfont;
|
||||||
} else {
|
} else {
|
||||||
/* Regardless of whether or not a fallback font is found, the
|
/* Regardless of whether or not a fallback font is found, the
|
||||||
* character must be drawn. */
|
* character must be drawn. */
|
||||||
charexists = 1;
|
charexists = 1;
|
||||||
|
|
||||||
for (i = 0; i < nomatches_len; ++i) {
|
for (i = 0; i < nomatches_len; ++i) {
|
||||||
/* avoid calling XftFontMatch if we know we won't find a match */
|
/* avoid calling XftFontMatch if we know we won't find a match */
|
||||||
if (utf8codepoint == nomatches.codepoint[i])
|
if (utf8codepoint == nomatches.codepoint[i])
|
||||||
goto no_match;
|
goto no_match;
|
||||||
}
|
}
|
||||||
|
|
||||||
fccharset = FcCharSetCreate();
|
fccharset = FcCharSetCreate();
|
||||||
FcCharSetAddChar(fccharset, utf8codepoint);
|
FcCharSetAddChar(fccharset, utf8codepoint);
|
||||||
|
|
||||||
if (!drw->fonts->pattern) {
|
if (!drw->fonts->pattern) {
|
||||||
/* Refer to the comment in xfont_create for more information. */
|
/* Refer to the comment in xfont_create for more information. */
|
||||||
die("the first font in the cache must be loaded from a font string.");
|
die("the first font in the cache must be loaded from a font string.");
|
||||||
}
|
}
|
||||||
|
|
||||||
fcpattern = FcPatternDuplicate(drw->fonts->pattern);
|
fcpattern = FcPatternDuplicate(drw->fonts->pattern);
|
||||||
FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
|
FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
|
||||||
FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
|
FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
|
||||||
FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
|
|
||||||
|
|
||||||
FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
|
FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
|
||||||
FcDefaultSubstitute(fcpattern);
|
FcDefaultSubstitute(fcpattern);
|
||||||
match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
|
match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
|
||||||
|
|
||||||
FcCharSetDestroy(fccharset);
|
FcCharSetDestroy(fccharset);
|
||||||
FcPatternDestroy(fcpattern);
|
FcPatternDestroy(fcpattern);
|
||||||
|
|
||||||
if (match) {
|
if (match) {
|
||||||
usedfont = xfont_create(drw, NULL, match);
|
usedfont = xfont_create(drw, NULL, match);
|
||||||
if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
|
if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
|
||||||
for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
|
for (curfont = drw->fonts; curfont->next; curfont = curfont->next); /* NOP */
|
||||||
; /* NOP */
|
curfont->next = usedfont;
|
||||||
curfont->next = usedfont;
|
} else {
|
||||||
} else {
|
xfont_free(usedfont);
|
||||||
xfont_free(usedfont);
|
nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint;
|
||||||
nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint;
|
no_match:
|
||||||
no_match:
|
usedfont = drw->fonts;
|
||||||
usedfont = drw->fonts;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (d)
|
||||||
if (d)
|
XftDrawDestroy(d);
|
||||||
XftDrawDestroy(d);
|
|
||||||
|
|
||||||
return x + (render ? w : 0);
|
return x + (render ? w : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
|
drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) {
|
||||||
{
|
if (!drw)
|
||||||
if (!drw)
|
return;
|
||||||
return;
|
|
||||||
|
|
||||||
XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
|
XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
|
||||||
XSync(drw->dpy, False);
|
XSync(drw->dpy, False);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
drw_fontset_getwidth(Drw *drw, const char *text)
|
drw_fontset_getwidth(Drw *drw, const char *text) {
|
||||||
{
|
if (!drw || !drw->fonts || !text)
|
||||||
if (!drw || !drw->fonts || !text)
|
return 0;
|
||||||
return 0;
|
return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
|
||||||
return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n)
|
drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n) {
|
||||||
{
|
unsigned int tmp = 0;
|
||||||
unsigned int tmp = 0;
|
if (drw && drw->fonts && text && n)
|
||||||
if (drw && drw->fonts && text && n)
|
tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n);
|
||||||
tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n);
|
return MIN(n, tmp);
|
||||||
return MIN(n, tmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
|
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) {
|
||||||
{
|
XGlyphInfo ext;
|
||||||
XGlyphInfo ext;
|
|
||||||
|
|
||||||
if (!font || !text)
|
if (!font || !text)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
|
XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *) text, len, &ext);
|
||||||
if (w)
|
if (w)
|
||||||
*w = ext.xOff;
|
*w = ext.xOff;
|
||||||
if (h)
|
if (h)
|
||||||
*h = font->h;
|
*h = font->h;
|
||||||
}
|
}
|
||||||
|
|
||||||
Cur *
|
Cur *
|
||||||
drw_cur_create(Drw *drw, int shape)
|
drw_cur_create(Drw *drw, int shape) {
|
||||||
{
|
Cur *cur;
|
||||||
Cur *cur;
|
|
||||||
|
|
||||||
if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
|
if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
cur->cursor = XCreateFontCursor(drw->dpy, shape);
|
cur->cursor = XCreateFontCursor(drw->dpy, shape);
|
||||||
|
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
drw_cur_free(Drw *drw, Cur *cursor)
|
drw_cur_free(Drw *drw, Cur *cursor) {
|
||||||
{
|
if (!cursor)
|
||||||
if (!cursor)
|
return;
|
||||||
return;
|
|
||||||
|
|
||||||
XFreeCursor(drw->dpy, cursor->cursor);
|
XFreeCursor(drw->dpy, cursor->cursor);
|
||||||
free(cursor);
|
free(cursor);
|
||||||
}
|
}
|
||||||
|
|
46
src/drw.h
46
src/drw.h
|
@ -1,57 +1,69 @@
|
||||||
/* See LICENSE file for copyright and license details. */
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Cursor cursor;
|
Cursor cursor;
|
||||||
} Cur;
|
} Cur;
|
||||||
|
|
||||||
typedef struct Fnt {
|
typedef struct Fnt {
|
||||||
Display *dpy;
|
Display *dpy;
|
||||||
unsigned int h;
|
unsigned int h;
|
||||||
XftFont *xfont;
|
XftFont *xfont;
|
||||||
FcPattern *pattern;
|
FcPattern *pattern;
|
||||||
struct Fnt *next;
|
struct Fnt *next;
|
||||||
} Fnt;
|
} Fnt;
|
||||||
|
|
||||||
enum { ColFg, ColBg, ColBorder }; /* Clr scheme index */
|
enum {
|
||||||
|
ColFg, ColBg, ColBorder
|
||||||
|
}; /* Clr scheme index */
|
||||||
typedef XftColor Clr;
|
typedef XftColor Clr;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int w, h;
|
unsigned int w, h;
|
||||||
Display *dpy;
|
Display *dpy;
|
||||||
int screen;
|
int screen;
|
||||||
Window root;
|
Window root;
|
||||||
Drawable drawable;
|
Drawable drawable;
|
||||||
GC gc;
|
GC gc;
|
||||||
Clr *scheme;
|
Clr *scheme;
|
||||||
Fnt *fonts;
|
Fnt *fonts;
|
||||||
} Drw;
|
} Drw;
|
||||||
|
|
||||||
/* Drawable abstraction */
|
/* Drawable abstraction */
|
||||||
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
|
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
|
||||||
|
|
||||||
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
|
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
|
||||||
|
|
||||||
void drw_free(Drw *drw);
|
void drw_free(Drw *drw);
|
||||||
|
|
||||||
/* Fnt abstraction */
|
/* Fnt abstraction */
|
||||||
Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
|
Fnt *drw_fontset_create(Drw *drw, const char *fonts[], size_t fontcount);
|
||||||
void drw_fontset_free(Fnt* set);
|
|
||||||
|
void drw_fontset_free(Fnt *set);
|
||||||
|
|
||||||
unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
|
unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
|
||||||
|
|
||||||
unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n);
|
unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n);
|
||||||
|
|
||||||
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
|
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
|
||||||
|
|
||||||
/* Colorscheme abstraction */
|
/* Colorscheme abstraction */
|
||||||
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
|
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
|
||||||
|
|
||||||
Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
|
Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
|
||||||
|
|
||||||
/* Cursor abstraction */
|
/* Cursor abstraction */
|
||||||
Cur *drw_cur_create(Drw *drw, int shape);
|
Cur *drw_cur_create(Drw *drw, int shape);
|
||||||
|
|
||||||
void drw_cur_free(Drw *drw, Cur *cursor);
|
void drw_cur_free(Drw *drw, Cur *cursor);
|
||||||
|
|
||||||
/* Drawing context manipulation */
|
/* Drawing context manipulation */
|
||||||
void drw_setfontset(Drw *drw, Fnt *set);
|
void drw_setfontset(Drw *drw, Fnt *set);
|
||||||
|
|
||||||
void drw_setscheme(Drw *drw, Clr *scm);
|
void drw_setscheme(Drw *drw, Clr *scm);
|
||||||
|
|
||||||
/* Drawing functions */
|
/* Drawing functions */
|
||||||
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
|
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);
|
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 */
|
/* Map functions */
|
||||||
|
|
184
src/keys/keys.c
184
src/keys/keys.c
|
@ -1,184 +0,0 @@
|
||||||
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
|
|
||||||
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
|
||||||
|
|
||||||
/* commands */
|
|
||||||
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
|
|
||||||
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", norm_bg,
|
|
||||||
"-nf", norm_fg, "-sb", sel_bg, "-sf", sel_fg, NULL };
|
|
||||||
static const char *termcmd[] = { TERMINAL, NULL };
|
|
||||||
|
|
||||||
/* key definitions */
|
|
||||||
#define MODKEY Mod4Mask // win/super key
|
|
||||||
|
|
||||||
#define TAGKEYS(KEY,TAG) \
|
|
||||||
{1, {{MODKEY, KEY}}, view, {.ui = 1 << TAG} }, \
|
|
||||||
{1, {{MODKEY|ControlMask, KEY}}, toggleview, {.ui = 1 << TAG} }, \
|
|
||||||
{1, {{MODKEY|ShiftMask, KEY}}, tag, {.ui = 1 << TAG} }, \
|
|
||||||
{1, {{MODKEY|ControlMask|ShiftMask, KEY}}, toggletag, {.ui = 1 << TAG} },
|
|
||||||
|
|
||||||
// X11 keysym definitions
|
|
||||||
#include <X11/XF86keysym.h> // req (libxinerama1 and libxinerama-dev)
|
|
||||||
static Keychord keychords[] = {
|
|
||||||
/* modifier key function argument */
|
|
||||||
/* ---------------------------------- Apps Keys ---------------------------------- */
|
|
||||||
// Dmenu (launcher)
|
|
||||||
{1, {{MODKEY|ShiftMask, XK_d}}, spawn, {.v = dmenucmd } },
|
|
||||||
// Rofi launcher (small)
|
|
||||||
{1, {{MODKEY|ShiftMask|ControlMask, XK_d}}, spawn, SHCMD("rofi -show drun") },
|
|
||||||
// Start the main terminal
|
|
||||||
{1, {{MODKEY, XK_Return}}, spawn, {.v = termcmd } },
|
|
||||||
// Start the alacritty terminal
|
|
||||||
{2, {{MODKEY, XK_t}, {0, XK_a}}, spawn, SHCMD("alacritty") },
|
|
||||||
// Start the alacritty terminal with tmux
|
|
||||||
{2, {{MODKEY, XK_t}, {ShiftMask, XK_a}}, spawn, SHCMD("alacritty -e tmux") },
|
|
||||||
// kitty
|
|
||||||
{2, {{MODKEY, XK_t}, {0, XK_k}}, spawn, SHCMD("kitty") },
|
|
||||||
// kitty with tmux
|
|
||||||
{2, {{MODKEY, XK_t}, {ShiftMask, XK_k}}, spawn, SHCMD("kitty -e tmux") },
|
|
||||||
/************************************* File browsers *************************************/
|
|
||||||
// GUI filebrowser (pcmanfm)
|
|
||||||
{2, {{MODKEY|ShiftMask, XK_f}, {0, XK_g}}, spawn, SHCMD(GUI_FILEMANAGER) },
|
|
||||||
// Rofi file browser (small)
|
|
||||||
{2, {{MODKEY|ShiftMask, XK_f}, {0, XK_f}}, spawn, SHCMD("rofi -show filebrowser") },
|
|
||||||
// ranger
|
|
||||||
{2, {{MODKEY|ShiftMask, XK_f}, {0, XK_r}}, spawn, SHCMD(TERMINAL " -e ranger") },
|
|
||||||
/************************************* Start the web browers *************************************/
|
|
||||||
// Google chrome stable
|
|
||||||
{2, {{MODKEY, XK_w}, {0, XK_g}}, spawn, SHCMD(WEBBROWSER) },
|
|
||||||
// Tor brower
|
|
||||||
{2, {{MODKEY, XK_w}, {0, XK_t}}, spawn, SHCMD("tor-browser") },
|
|
||||||
/************************************* Start the caht/email/\* apps *************************************/
|
|
||||||
// Discord
|
|
||||||
{2, {{MODKEY, XK_c}, {0, XK_d}}, spawn, SHCMD("discord") },
|
|
||||||
// Obsidian
|
|
||||||
{2, {{MODKEY, XK_c}, {0, XK_o}}, spawn, SHCMD("obsidian") },
|
|
||||||
/************************************* Start the dev apps *************************************/
|
|
||||||
// Jetbrains toolbox
|
|
||||||
{2, {{MODKEY, XK_a}, {0, XK_j}}, spawn, SHCMD("jetbrains-toolbox") },
|
|
||||||
// NeoVim
|
|
||||||
{2, {{MODKEY, XK_a}, {0, XK_n}}, spawn, SHCMD(TERMINAL " -e nvim") },
|
|
||||||
// Vim
|
|
||||||
{2, {{MODKEY, XK_a}, {0, XK_v}}, spawn, SHCMD(TERMINAL " -e vim") },
|
|
||||||
// emacs
|
|
||||||
{2, {{MODKEY, XK_a}, {0, XK_e}}, spawn, SHCMD("emacs") },
|
|
||||||
/************************************* Start personalize apps *************************************/
|
|
||||||
// nitrogen
|
|
||||||
{2, {{MODKEY, XK_p}, {0, XK_b}}, spawn, SHCMD("nitrogen") },
|
|
||||||
// nm-connection-editor
|
|
||||||
{2, {{MODKEY, XK_p}, {0, XK_n}}, spawn, SHCMD("nm-connection-editor") },
|
|
||||||
/************************************* Start multi media apps *************************************/
|
|
||||||
// cmus
|
|
||||||
{2, {{MODKEY, XK_m}, {0, XK_c}}, spawn, SHCMD("sh -c \"" TERMINAL " -e cmus\" & sh -c \"cmus-rpc --link\"") },
|
|
||||||
// vlc
|
|
||||||
{2, {{MODKEY, XK_m}, {0, XK_v}}, spawn, SHCMD("vlc") },
|
|
||||||
// vlc in the main terminal
|
|
||||||
{2, {{MODKEY, XK_m}, {ShiftMask, XK_v}}, spawn, SHCMD(TERMINAL "nvlc") },
|
|
||||||
/************************************* Start the emoji piker apps *************************************/
|
|
||||||
// Emoji selector (rofi)
|
|
||||||
{1, {{Mod4Mask, XK_e}}, spawn, SHCMD("rofi -show emoji") },
|
|
||||||
/************************************* dwm keys *************************************/
|
|
||||||
// Full screen mode
|
|
||||||
{1, {{MODKEY, XK_f}}, fullscreen, {0} },
|
|
||||||
// Toggle the slstatus bar (hide/show)
|
|
||||||
{1, {{MODKEY, XK_b}}, togglebar, {0} },
|
|
||||||
// Change the focus
|
|
||||||
{1, {{MODKEY, XK_j}}, focusstack, {.i = +1 } },
|
|
||||||
{1, {{MODKEY, XK_k}}, focusstack, {.i = -1 } },
|
|
||||||
// Change the stack layout (horizontal/virtecal)
|
|
||||||
{1, {{MODKEY, XK_i}}, incnmaster, {.i = +1 } },
|
|
||||||
{1, {{MODKEY, XK_d}}, incnmaster, {.i = -1 } },
|
|
||||||
// Change the focus window size (in the tile mode)
|
|
||||||
{1, {{MODKEY, XK_h}}, setmfact, {.f = -0.05} },
|
|
||||||
{1, {{MODKEY, XK_l}}, setmfact, {.f = +0.05} },
|
|
||||||
// { MODKEY, XK_Return, zoom, {0} },
|
|
||||||
{1, {{MODKEY, XK_Tab}}, view, {0} },
|
|
||||||
|
|
||||||
{1, {{MODKEY|ShiftMask, XK_j}}, movestack, {.i = +1 } },
|
|
||||||
{1, {{MODKEY|ShiftMask, XK_k}}, movestack, {.i = -1 } },
|
|
||||||
// Toogle styky mode
|
|
||||||
{1, {{MODKEY|ShiftMask, XK_s}}, togglesticky, {0} },
|
|
||||||
|
|
||||||
// Quit from the foucsed window (kill)
|
|
||||||
{2, {{MODKEY, XK_q}, {0, XK_q}}, killclient, {0} },
|
|
||||||
/************************* Switch between layouts *************************/
|
|
||||||
// Tiled layout
|
|
||||||
{2, {{MODKEY, XK_s}, {0, XK_t}}, setlayout, {.v = &layouts[0]} },
|
|
||||||
// Floating layout
|
|
||||||
{2, {{MODKEY, XK_s}, {0, XK_f}}, setlayout, {.v = &layouts[1]} },
|
|
||||||
// Monocle layout
|
|
||||||
{2, {{MODKEY, XK_s}, {0, XK_m}}, setlayout, {.v = &layouts[2]} },
|
|
||||||
// Grid layout
|
|
||||||
{2, {{MODKEY, XK_s}, {0, XK_g}}, setlayout, {.v = &layouts[3]} },
|
|
||||||
// Spiral layout
|
|
||||||
{2, {{MODKEY, XK_s}, {0, XK_r}}, setlayout, {.v = &layouts[4]} },
|
|
||||||
// Dwindle layout
|
|
||||||
{2, {{MODKEY, XK_s}, {ShiftMask, XK_r}}, setlayout, {.v = &layouts[5]} },
|
|
||||||
// Centerd master layout
|
|
||||||
{2, {{MODKEY, XK_s}, {0, XK_c}}, setlayout, {.v = &layouts[6]} },
|
|
||||||
// Centerd floating master layout
|
|
||||||
{2, {{MODKEY, XK_s}, {ShiftMask, XK_c}}, setlayout, {.v = &layouts[7]} },
|
|
||||||
|
|
||||||
// Toggle between current layout and tile layout
|
|
||||||
{2, {{MODKEY, XK_s}, {0, XK_space}}, setlayout, {0} },
|
|
||||||
// Toggle floating window
|
|
||||||
{1, {{MODKEY|Mod1Mask, XK_f}}, togglefloating, {0} },
|
|
||||||
// View all tags
|
|
||||||
{1, {{MODKEY, XK_0}}, view, {.ui = ~0 } },
|
|
||||||
// Mirror the current tagg in all tags
|
|
||||||
{1, {{MODKEY|ShiftMask, XK_0}}, tag, {.ui = ~0 } },
|
|
||||||
// I don't know
|
|
||||||
{1, {{MODKEY, XK_comma}}, focusmon, {.i = -1 } },
|
|
||||||
{1, {{MODKEY, XK_period}}, focusmon, {.i = +1 } },
|
|
||||||
{1, {{MODKEY|ShiftMask, XK_comma}}, tagmon, {.i = -1 } },
|
|
||||||
{1, {{MODKEY|ShiftMask, XK_period}}, tagmon, {.i = +1 } },
|
|
||||||
/************************* Tag keys *************************/
|
|
||||||
TAGKEYS( XK_1, 0)
|
|
||||||
TAGKEYS( XK_2, 1)
|
|
||||||
TAGKEYS( XK_3, 2)
|
|
||||||
TAGKEYS( XK_4, 3)
|
|
||||||
TAGKEYS( XK_5, 4)
|
|
||||||
TAGKEYS( XK_6, 5)
|
|
||||||
TAGKEYS( XK_7, 6)
|
|
||||||
TAGKEYS( XK_8, 7)
|
|
||||||
TAGKEYS( XK_9, 8)
|
|
||||||
/* ---------------------------------- Control Keys ---------------------------------- */
|
|
||||||
// Brightness controllers (requires xbacklight)
|
|
||||||
{1, {{0, XF86XK_MonBrightnessUp}}, spawn, SHCMD("xbacklight -inc 5") },
|
|
||||||
{1, {{0, XF86XK_MonBrightnessDown}}, spawn, SHCMD("xbacklight -dec 5") },
|
|
||||||
// Sound controllers (requires pamixer)
|
|
||||||
{1, {{0, XF86XK_AudioRaiseVolume}}, spawn, SHCMD("pamixer --allow-boost -i 4") },
|
|
||||||
{1, {{0, XF86XK_AudioLowerVolume}}, spawn, SHCMD("pamixer --allow-boost -d 4") },
|
|
||||||
{1, {{0, XF86XK_AudioMute}}, spawn, SHCMD("pamixer -t") },
|
|
||||||
// Media controls (requires playerctl)
|
|
||||||
{1, {{0, XF86XK_AudioPlay}}, spawn, SHCMD("playerctl play-pause") },
|
|
||||||
{1, {{0, XF86XK_AudioStop}}, spawn, SHCMD("playerctl stop") },
|
|
||||||
{1, {{0, XF86XK_AudioNext}}, spawn, SHCMD("playerctl next") },
|
|
||||||
{1, {{0, XF86XK_AudioPrev}}, spawn, SHCMD("playerctl previous") },
|
|
||||||
// Mute and unmute mic
|
|
||||||
{1, {{0, XF86XK_AudioMicMute}}, spawn, SHCMD("pactl set-source-mute @DEFAULT_SOURCE@ toggle") },
|
|
||||||
// Take a screenshot
|
|
||||||
{1, {{0, XK_Print}}, spawn, SHCMD(SCREENSHOT) },
|
|
||||||
/* ---------------------------------- lock Keys ---------------------------------- */
|
|
||||||
// Lock the screen
|
|
||||||
{1, {{MODKEY|ShiftMask, XK_x}}, spawn, SHCMD("betterlockscreen -l dim") },
|
|
||||||
// Kill dwm (super + shift + alt + q)
|
|
||||||
{1, {{MODKEY|ShiftMask|Mod1Mask, XK_q}}, quit, {0} },
|
|
||||||
};
|
|
||||||
|
|
||||||
/* button definitions */
|
|
||||||
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
|
|
||||||
static Button buttons[] = {
|
|
||||||
/* click event mask button function argument */
|
|
||||||
{ ClkTagBar, MODKEY, Button1, tag, {0} },
|
|
||||||
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
|
|
||||||
{ ClkWinTitle, 0, Button2, zoom, {0} },
|
|
||||||
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
|
|
||||||
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
|
|
||||||
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
|
|
||||||
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
|
|
||||||
{ ClkTagBar, 0, Button1, view, {0} },
|
|
||||||
{ ClkTagBar, 0, Button3, toggleview, {0} },
|
|
||||||
{ ClkTagBar, MODKEY, Button1, tag, {0} },
|
|
||||||
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
#ifndef keys_H
|
|
||||||
#define keys_H
|
|
||||||
|
|
||||||
#include "keys.c"
|
|
||||||
|
|
||||||
#endif // !keys.h
|
|
|
@ -1,102 +1,103 @@
|
||||||
|
#include "../archy_dwm.h"
|
||||||
|
#include "../util.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
centeredmaster(Monitor *m)
|
centeredmaster(Monitor *m) {
|
||||||
{
|
unsigned int i, n, h, mw, mx, my, oty, ety, tw;
|
||||||
unsigned int i, n, h, mw, mx, my, oty, ety, tw;
|
Client *c;
|
||||||
Client *c;
|
|
||||||
|
|
||||||
/* count number of clients in the selected monitor */
|
/* count number of clients in the selected monitor */
|
||||||
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
|
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* initialize areas */
|
/* initialize areas */
|
||||||
mw = m->ww;
|
mw = m->ww;
|
||||||
mx = 0;
|
mx = 0;
|
||||||
my = 0;
|
my = 0;
|
||||||
tw = mw;
|
tw = mw;
|
||||||
|
|
||||||
if (n > m->nmaster) {
|
if (n > m->nmaster) {
|
||||||
/* go mfact box in the center if more than nmaster clients */
|
/* go mfact box in the center if more than nmaster clients */
|
||||||
mw = m->nmaster ? m->ww * m->mfact : 0;
|
mw = m->nmaster ? m->ww * m->mfact : 0;
|
||||||
tw = m->ww - mw;
|
tw = m->ww - mw;
|
||||||
|
|
||||||
if (n - m->nmaster > 1) {
|
if (n - m->nmaster > 1) {
|
||||||
/* only one client */
|
/* only one client */
|
||||||
mx = (m->ww - mw) / 2;
|
mx = (m->ww - mw) / 2;
|
||||||
tw = (m->ww - mw) / 2;
|
tw = (m->ww - mw) / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
oty = 0;
|
oty = 0;
|
||||||
ety = 0;
|
ety = 0;
|
||||||
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
if (i < m->nmaster) {
|
if (i < m->nmaster) {
|
||||||
/* nmaster clients are stacked vertically, in the center
|
/* nmaster clients are stacked vertically, in the center
|
||||||
* of the screen */
|
* of the screen */
|
||||||
h = (m->wh - my) / (MIN(n, m->nmaster) - i);
|
h = (m->wh - my) / (MIN(n, m->nmaster) - i);
|
||||||
resize(c, m->wx + mx, m->wy + my, mw - (2*c->bw),
|
resize(c, m->wx + mx, m->wy + my, mw - (2 * c->bw),
|
||||||
h - (2*c->bw), 0);
|
h - (2 * c->bw), 0);
|
||||||
my += HEIGHT(c);
|
my += HEIGHT(c);
|
||||||
} else {
|
} else {
|
||||||
/* stack clients are stacked vertically */
|
/* stack clients are stacked vertically */
|
||||||
if ((i - m->nmaster) % 2 ) {
|
if ((i - m->nmaster) % 2) {
|
||||||
h = (m->wh - ety) / ( (1 + n - i) / 2);
|
h = (m->wh - ety) / ((1 + n - i) / 2);
|
||||||
resize(c, m->wx, m->wy + ety, tw - (2*c->bw),
|
resize(c, m->wx, m->wy + ety, tw - (2 * c->bw),
|
||||||
h - (2*c->bw), 0);
|
h - (2 * c->bw), 0);
|
||||||
ety += HEIGHT(c);
|
ety += HEIGHT(c);
|
||||||
} else {
|
} else {
|
||||||
h = (m->wh - oty) / ((1 + n - i) / 2);
|
h = (m->wh - oty) / ((1 + n - i) / 2);
|
||||||
resize(c, m->wx + mx + mw, m->wy + oty,
|
resize(c, m->wx + mx + mw, m->wy + oty,
|
||||||
tw - (2*c->bw), h - (2*c->bw), 0);
|
tw - (2 * c->bw), h - (2 * c->bw), 0);
|
||||||
oty += HEIGHT(c);
|
oty += HEIGHT(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
centeredfloatingmaster(Monitor *m)
|
centeredfloatingmaster(Monitor *m) {
|
||||||
{
|
unsigned int i, n, w, mh, mw, mx, mxo, my, myo, tx;
|
||||||
unsigned int i, n, w, mh, mw, mx, mxo, my, myo, tx;
|
Client *c;
|
||||||
Client *c;
|
|
||||||
|
|
||||||
/* count number of clients in the selected monitor */
|
/* count number of clients in the selected monitor */
|
||||||
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
|
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* initialize nmaster area */
|
/* initialize nmaster area */
|
||||||
if (n > m->nmaster) {
|
if (n > m->nmaster) {
|
||||||
/* go mfact box in the center if more than nmaster clients */
|
/* go mfact box in the center if more than nmaster clients */
|
||||||
if (m->ww > m->wh) {
|
if (m->ww > m->wh) {
|
||||||
mw = m->nmaster ? m->ww * m->mfact : 0;
|
mw = m->nmaster ? m->ww * m->mfact : 0;
|
||||||
mh = m->nmaster ? m->wh * 0.9 : 0;
|
mh = m->nmaster ? m->wh * 0.9 : 0;
|
||||||
} else {
|
} else {
|
||||||
mh = m->nmaster ? m->wh * m->mfact : 0;
|
mh = m->nmaster ? m->wh * m->mfact : 0;
|
||||||
mw = m->nmaster ? m->ww * 0.9 : 0;
|
mw = m->nmaster ? m->ww * 0.9 : 0;
|
||||||
}
|
}
|
||||||
mx = mxo = (m->ww - mw) / 2;
|
mx = mxo = (m->ww - mw) / 2;
|
||||||
my = myo = (m->wh - mh) / 2;
|
my = myo = (m->wh - mh) / 2;
|
||||||
} else {
|
} else {
|
||||||
/* go fullscreen if all clients are in the master area */
|
/* go fullscreen if all clients are in the master area */
|
||||||
mh = m->wh;
|
mh = m->wh;
|
||||||
mw = m->ww;
|
mw = m->ww;
|
||||||
mx = mxo = 0;
|
mx = mxo = 0;
|
||||||
my = myo = 0;
|
my = myo = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = tx = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
for (i = tx = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
if (i < m->nmaster) {
|
if (i < m->nmaster) {
|
||||||
/* nmaster clients are stacked horizontally, in the center
|
/* nmaster clients are stacked horizontally, in the center
|
||||||
* of the screen */
|
* of the screen */
|
||||||
w = (mw + mxo - mx) / (MIN(n, m->nmaster) - i);
|
w = (mw + mxo - mx) / (MIN(n, m->nmaster) - i);
|
||||||
resize(c, m->wx + mx, m->wy + my, w - (2*c->bw),
|
resize(c, m->wx + mx, m->wy + my, w - (2 * c->bw),
|
||||||
mh - (2*c->bw), 0);
|
mh - (2 * c->bw), 0);
|
||||||
mx += WIDTH(c);
|
mx += WIDTH(c);
|
||||||
} else {
|
} else {
|
||||||
/* stack clients are stacked horizontally */
|
/* stack clients are stacked horizontally */
|
||||||
w = (m->ww - tx) / (n - i);
|
w = (m->ww - tx) / (n - i);
|
||||||
resize(c, m->wx + tx, m->wy, w - (2*c->bw),
|
resize(c, m->wx + tx, m->wy, w - (2 * c->bw),
|
||||||
m->wh - (2*c->bw), 0);
|
m->wh - (2 * c->bw), 0);
|
||||||
tx += WIDTH(c);
|
tx += WIDTH(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,4 +7,4 @@ static void centeredfloatingmaster(Monitor *m);
|
||||||
#include "centeredmaster.c"
|
#include "centeredmaster.c"
|
||||||
|
|
||||||
|
|
||||||
#endif // !centeredmaster.h
|
#endif // centeredmaster_H
|
||||||
|
|
|
@ -1,66 +1,65 @@
|
||||||
|
#include "../archy_dwm.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
fibonacci(Monitor *mon, int s) {
|
fibonacci(Monitor *mon, int s) {
|
||||||
unsigned int i, n, nx, ny, nw, nh;
|
unsigned int i, n, nx, ny, nw, nh;
|
||||||
Client *c;
|
Client *c;
|
||||||
|
|
||||||
for(n = 0, c = nexttiled(mon->clients); c; c = nexttiled(c->next), n++);
|
for (n = 0, c = nexttiled(mon->clients); c; c = nexttiled(c->next), n++);
|
||||||
if(n == 0)
|
if (n == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nx = mon->wx;
|
nx = mon->wx;
|
||||||
ny = 0;
|
ny = 0;
|
||||||
nw = mon->ww;
|
nw = mon->ww;
|
||||||
nh = mon->wh;
|
nh = mon->wh;
|
||||||
|
|
||||||
for(i = 0, c = nexttiled(mon->clients); c; c = nexttiled(c->next)) {
|
for (i = 0, c = nexttiled(mon->clients); c; c = nexttiled(c->next)) {
|
||||||
if((i % 2 && nh / 2 > 2 * c->bw)
|
if ((i % 2 && nh / 2 > 2 * c->bw)
|
||||||
|| (!(i % 2) && nw / 2 > 2 * c->bw)) {
|
|| (!(i % 2) && nw / 2 > 2 * c->bw)) {
|
||||||
if(i < n - 1) {
|
if (i < n - 1) {
|
||||||
if(i % 2)
|
if (i % 2)
|
||||||
nh /= 2;
|
nh /= 2;
|
||||||
else
|
else
|
||||||
nw /= 2;
|
nw /= 2;
|
||||||
if((i % 4) == 2 && !s)
|
if ((i % 4) == 2 && !s)
|
||||||
nx += nw;
|
nx += nw;
|
||||||
else if((i % 4) == 3 && !s)
|
else if ((i % 4) == 3 && !s)
|
||||||
ny += nh;
|
ny += nh;
|
||||||
}
|
}
|
||||||
if((i % 4) == 0) {
|
if ((i % 4) == 0) {
|
||||||
if(s)
|
if (s)
|
||||||
ny += nh;
|
ny += nh;
|
||||||
else
|
else
|
||||||
ny -= nh;
|
ny -= nh;
|
||||||
}
|
} else if ((i % 4) == 1)
|
||||||
else if((i % 4) == 1)
|
nx += nw;
|
||||||
nx += nw;
|
else if ((i % 4) == 2)
|
||||||
else if((i % 4) == 2)
|
ny += nh;
|
||||||
ny += nh;
|
else if ((i % 4) == 3) {
|
||||||
else if((i % 4) == 3) {
|
if (s)
|
||||||
if(s)
|
nx += nw;
|
||||||
nx += nw;
|
else
|
||||||
else
|
nx -= nw;
|
||||||
nx -= nw;
|
}
|
||||||
}
|
if (i == 0) {
|
||||||
if(i == 0)
|
if (n != 1)
|
||||||
{
|
nw = mon->ww * mon->mfact;
|
||||||
if(n != 1)
|
ny = mon->wy;
|
||||||
nw = mon->ww * mon->mfact;
|
} else if (i == 1)
|
||||||
ny = mon->wy;
|
nw = mon->ww - nw;
|
||||||
}
|
i++;
|
||||||
else if(i == 1)
|
}
|
||||||
nw = mon->ww - nw;
|
resize(c, nx, ny, nw - 2 * c->bw, nh - 2 * c->bw, False);
|
||||||
i++;
|
}
|
||||||
}
|
|
||||||
resize(c, nx, ny, nw - 2 * c->bw, nh - 2 * c->bw, False);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dwindle(Monitor *mon) {
|
dwindle(Monitor *mon) {
|
||||||
fibonacci(mon, 1);
|
fibonacci(mon, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
spiral(Monitor *mon) {
|
spiral(Monitor *mon) {
|
||||||
fibonacci(mon, 0);
|
fibonacci(mon, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,29 @@
|
||||||
|
#include "../archy_dwm.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
grid(Monitor *m) {
|
grid(Monitor *m) {
|
||||||
unsigned int i, n, cx, cy, cw, ch, aw, ah, cols, rows;
|
unsigned int i, n, cx, cy, cw, ch, aw, ah, cols, rows;
|
||||||
Client *c;
|
Client *c;
|
||||||
|
|
||||||
for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next))
|
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next))
|
||||||
n++;
|
n++;
|
||||||
|
|
||||||
/* grid dimensions */
|
/* grid dimensions */
|
||||||
for(rows = 0; rows <= n/2; rows++)
|
for (rows = 0; rows <= n / 2; rows++)
|
||||||
if(rows*rows >= n)
|
if (rows * rows >= n)
|
||||||
break;
|
break;
|
||||||
cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows;
|
cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows;
|
||||||
|
|
||||||
/* window geoms (cell height/width) */
|
/* window geoms (cell height/width) */
|
||||||
ch = m->wh / (rows ? rows : 1);
|
ch = m->wh / (rows ? rows : 1);
|
||||||
cw = m->ww / (cols ? cols : 1);
|
cw = m->ww / (cols ? cols : 1);
|
||||||
for(i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
|
||||||
cx = m->wx + (i / rows) * cw;
|
cx = m->wx + (i / rows) * cw;
|
||||||
cy = m->wy + (i % rows) * ch;
|
cy = m->wy + (i % rows) * ch;
|
||||||
/* adjust height/width of last row/column's windows */
|
/* adjust height/width of last row/column's windows */
|
||||||
ah = ((i + 1) % rows == 0) ? m->wh - ch * rows : 0;
|
ah = ((i + 1) % rows == 0) ? m->wh - ch * rows : 0;
|
||||||
aw = (i >= rows * (cols - 1)) ? m->ww - cw * cols : 0;
|
aw = (i >= rows * (cols - 1)) ? m->ww - cw * cols : 0;
|
||||||
resize(c, cx, cy, cw - 2 * c->bw + aw, ch - 2 * c->bw + ah, False);
|
resize(c, cx, cy, cw - 2 * c->bw + aw, ch - 2 * c->bw + ah, False);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,15 +10,15 @@
|
||||||
|
|
||||||
// Layouts array
|
// Layouts array
|
||||||
static const Layout layouts[] = {
|
static const Layout layouts[] = {
|
||||||
/* symbol arrange function */
|
/* symbol arrange function */
|
||||||
{ "[]=", tile }, /* first entry is default */
|
{"[]=", tile}, /* first entry is default */
|
||||||
{ "><>", NULL }, /* no layout function means floating behavior */
|
{"><>", NULL}, /* no layout function means floating behavior */
|
||||||
{ "[M]", monocle }, // 2
|
{"[M]", monocle}, // 2
|
||||||
{ "HHH", grid }, // 3
|
{"HHH", grid}, // 3
|
||||||
{ "[@]", spiral }, // 4
|
{"[@]", spiral}, // 4
|
||||||
{ "[\\]", dwindle }, // 5
|
{"[\\]", dwindle}, // 5
|
||||||
{ "|M|", centeredmaster }, // 6
|
{"|M|", centeredmaster}, // 6
|
||||||
{ ">M>", centeredfloatingmaster }, // 7
|
{">M>", centeredfloatingmaster}, // 7
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // !layouts.h
|
#endif // layouts_H
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
void
|
#include "../archy_dwm.h"
|
||||||
monocle(Monitor *m)
|
#include "../util.h"
|
||||||
{
|
|
||||||
unsigned int n = 0;
|
|
||||||
Client *c;
|
|
||||||
|
|
||||||
for (c = m->clients; c; c = c->next)
|
void
|
||||||
if (ISVISIBLE(c))
|
monocle(Monitor *m) {
|
||||||
n++;
|
unsigned int n = 0;
|
||||||
if (n > 0) /* override layout symbol */
|
Client *c;
|
||||||
snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
|
|
||||||
for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
|
for (c = m->clients; c; c = c->next)
|
||||||
resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
|
if (ISVISIBLE(c))
|
||||||
|
n++;
|
||||||
|
if (n > 0) /* override layout symbol */
|
||||||
|
snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
|
||||||
|
for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
|
||||||
|
resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,29 @@
|
||||||
|
#include "../archy_dwm.h"
|
||||||
|
#include "../util.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
tile(Monitor *m)
|
tile(Monitor *m) {
|
||||||
{
|
unsigned int i, n, h, mw, my, ty;
|
||||||
unsigned int i, n, h, mw, my, ty;
|
Client *c;
|
||||||
Client *c;
|
|
||||||
|
|
||||||
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
|
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (n > m->nmaster)
|
if (n > m->nmaster)
|
||||||
mw = m->nmaster ? m->ww * m->mfact : 0;
|
mw = m->nmaster ? m->ww * m->mfact : 0;
|
||||||
else
|
else
|
||||||
mw = m->ww;
|
mw = m->ww;
|
||||||
for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
if (i < m->nmaster) {
|
if (i < m->nmaster) {
|
||||||
h = (m->wh - my) / (MIN(n, m->nmaster) - i);
|
h = (m->wh - my) / (MIN(n, m->nmaster) - i);
|
||||||
resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
|
resize(c, m->wx, m->wy + my, mw - (2 * c->bw), h - (2 * c->bw), 0);
|
||||||
if (my + HEIGHT(c) < m->wh)
|
if (my + HEIGHT(c) < m->wh)
|
||||||
my += HEIGHT(c);
|
my += HEIGHT(c);
|
||||||
} else {
|
} else {
|
||||||
h = (m->wh - ty) / (n - i);
|
h = (m->wh - ty) / (n - i);
|
||||||
resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
|
resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2 * c->bw), h - (2 * c->bw), 0);
|
||||||
if (ty + HEIGHT(c) < m->wh)
|
if (ty + HEIGHT(c) < m->wh)
|
||||||
ty += HEIGHT(c);
|
ty += HEIGHT(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,48 +1,50 @@
|
||||||
void
|
#include "archy_dwm.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
static void
|
||||||
movestack(const Arg *arg) {
|
movestack(const Arg *arg) {
|
||||||
Client *c = NULL, *p = NULL, *pc = NULL, *i;
|
Client *c = NULL, *p = NULL, *pc = NULL, *i;
|
||||||
|
|
||||||
if(arg->i > 0) {
|
if (arg->i > 0) {
|
||||||
/* find the client after selmon->sel */
|
/* find the client after selmon->sel */
|
||||||
for(c = selmon->sel->next; c && (!ISVISIBLE(c) || c->isfloating); c = c->next);
|
for (c = selmon->sel->next; c && (!ISVISIBLE(c) || c->isfloating); c = c->next);
|
||||||
if(!c)
|
if (!c)
|
||||||
for(c = selmon->clients; c && (!ISVISIBLE(c) || c->isfloating); c = c->next);
|
for (c = selmon->clients; c && (!ISVISIBLE(c) || c->isfloating); c = c->next);
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else {
|
/* find the client before selmon->sel */
|
||||||
/* find the client before selmon->sel */
|
for (i = selmon->clients; i != selmon->sel; i = i->next)
|
||||||
for(i = selmon->clients; i != selmon->sel; i = i->next)
|
if (ISVISIBLE(i) && !i->isfloating)
|
||||||
if(ISVISIBLE(i) && !i->isfloating)
|
c = i;
|
||||||
c = i;
|
if (!c)
|
||||||
if(!c)
|
for (; i; i = i->next)
|
||||||
for(; i; i = i->next)
|
if (ISVISIBLE(i) && !i->isfloating)
|
||||||
if(ISVISIBLE(i) && !i->isfloating)
|
c = i;
|
||||||
c = i;
|
}
|
||||||
}
|
/* find the client before selmon->sel and c */
|
||||||
/* find the client before selmon->sel and c */
|
for (i = selmon->clients; i && (!p || !pc); i = i->next) {
|
||||||
for(i = selmon->clients; i && (!p || !pc); i = i->next) {
|
if (i->next == selmon->sel)
|
||||||
if(i->next == selmon->sel)
|
p = i;
|
||||||
p = i;
|
if (i->next == c)
|
||||||
if(i->next == c)
|
pc = i;
|
||||||
pc = i;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* swap c and selmon->sel selmon->clients in the selmon->clients list */
|
/* swap c and selmon->sel selmon->clients in the selmon->clients list */
|
||||||
if(c && c != selmon->sel) {
|
if (c && c != selmon->sel) {
|
||||||
Client *temp = selmon->sel->next==c?selmon->sel:selmon->sel->next;
|
Client *temp = selmon->sel->next == c ? selmon->sel : selmon->sel->next;
|
||||||
selmon->sel->next = c->next==selmon->sel?c:c->next;
|
selmon->sel->next = c->next == selmon->sel ? c : c->next;
|
||||||
c->next = temp;
|
c->next = temp;
|
||||||
|
|
||||||
if(p && p != c)
|
if (p && p != c)
|
||||||
p->next = c;
|
p->next = c;
|
||||||
if(pc && pc != selmon->sel)
|
if (pc && pc != selmon->sel)
|
||||||
pc->next = selmon->sel;
|
pc->next = selmon->sel;
|
||||||
|
|
||||||
if(selmon->sel == selmon->clients)
|
if (selmon->sel == selmon->clients)
|
||||||
selmon->clients = c;
|
selmon->clients = c;
|
||||||
else if(c == selmon->clients)
|
else if (c == selmon->clients)
|
||||||
selmon->clients = selmon->sel;
|
selmon->clients = selmon->sel;
|
||||||
|
|
||||||
arrange(selmon);
|
arrange(selmon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,37 +6,37 @@
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
Display *d;
|
Display *d;
|
||||||
Window r, f, t = None;
|
Window r, f, t = None;
|
||||||
XSizeHints h;
|
XSizeHints h;
|
||||||
XEvent e;
|
XEvent e;
|
||||||
|
|
||||||
d = XOpenDisplay(NULL);
|
d = XOpenDisplay(NULL);
|
||||||
if (!d)
|
if (!d)
|
||||||
exit(1);
|
exit(1);
|
||||||
r = DefaultRootWindow(d);
|
r = DefaultRootWindow(d);
|
||||||
|
|
||||||
f = XCreateSimpleWindow(d, r, 100, 100, 400, 400, 0, 0, 0);
|
f = XCreateSimpleWindow(d, r, 100, 100, 400, 400, 0, 0, 0);
|
||||||
h.min_width = h.max_width = h.min_height = h.max_height = 400;
|
h.min_width = h.max_width = h.min_height = h.max_height = 400;
|
||||||
h.flags = PMinSize | PMaxSize;
|
h.flags = PMinSize | PMaxSize;
|
||||||
XSetWMNormalHints(d, f, &h);
|
XSetWMNormalHints(d, f, &h);
|
||||||
XStoreName(d, f, "floating");
|
XStoreName(d, f, "floating");
|
||||||
XMapWindow(d, f);
|
XMapWindow(d, f);
|
||||||
|
|
||||||
XSelectInput(d, f, ExposureMask);
|
XSelectInput(d, f, ExposureMask);
|
||||||
while (1) {
|
while (1) {
|
||||||
XNextEvent(d, &e);
|
XNextEvent(d, &e);
|
||||||
|
|
||||||
if (t == None) {
|
if (t == None) {
|
||||||
sleep(5);
|
sleep(5);
|
||||||
t = XCreateSimpleWindow(d, r, 50, 50, 100, 100, 0, 0, 0);
|
t = XCreateSimpleWindow(d, r, 50, 50, 100, 100, 0, 0, 0);
|
||||||
XSetTransientForHint(d, t, f);
|
XSetTransientForHint(d, t, f);
|
||||||
XStoreName(d, t, "transient");
|
XStoreName(d, t, "transient");
|
||||||
XMapWindow(d, t);
|
XMapWindow(d, t);
|
||||||
XSelectInput(d, t, ExposureMask);
|
XSelectInput(d, t, ExposureMask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XCloseDisplay(d);
|
XCloseDisplay(d);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
23
src/util.c
23
src/util.c
|
@ -6,18 +6,9 @@
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
void *
|
|
||||||
ecalloc(size_t nmemb, size_t size)
|
|
||||||
{
|
|
||||||
void *p;
|
|
||||||
|
|
||||||
if (!(p = calloc(nmemb, size)))
|
|
||||||
die("calloc:");
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
die(const char *fmt, ...) {
|
die(const char *fmt, ...)
|
||||||
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
|
@ -33,3 +24,13 @@ die(const char *fmt, ...) {
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
ecalloc(size_t nmemb, size_t size)
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
if (!(p = calloc(nmemb, size)))
|
||||||
|
die("calloc:");
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
19
src/util.h
19
src/util.h
|
@ -1,8 +1,25 @@
|
||||||
/* See LICENSE file for copyright and license details. */
|
#ifndef UTIL_H
|
||||||
|
#define UTIL_H
|
||||||
|
|
||||||
|
/* macros */
|
||||||
|
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
|
||||||
|
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
|
||||||
|
#define INTERSECT(x, y, w, h, m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
|
||||||
|
* MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
|
||||||
|
#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]) || C->issticky)
|
||||||
|
#define LENGTH(X) (sizeof X / sizeof X[0])
|
||||||
|
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
||||||
|
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
|
||||||
|
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
|
||||||
|
#define TAGMASK ((1 << LENGTH(tags)) - 1)
|
||||||
|
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad)
|
||||||
|
|
||||||
|
#define XEMBED_EMBEDDED_VERSION ((VERSION_MAJOR << 16) | VERSION_MINOR)
|
||||||
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||||
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
||||||
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
|
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
|
||||||
|
|
||||||
void die(const char *fmt, ...);
|
void die(const char *fmt, ...);
|
||||||
void *ecalloc(size_t nmemb, size_t size);
|
void *ecalloc(size_t nmemb, size_t size);
|
||||||
|
|
||||||
|
#endif // util_H
|
Loading…
Reference in a new issue