Compare commits
40 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
8e4f659772 | ||
|
99b45ee0d4 | ||
|
3f3811e80d | ||
|
fd9e12e7c5 | ||
|
4e8381c135 | ||
|
fa54da1744 | ||
|
6024c104c1 | ||
|
f0dd75e8c5 | ||
|
95131de64f | ||
|
e81decd079 | ||
|
ef6b5ee95a | ||
|
edb4762434 | ||
|
14dc678a7f | ||
|
9b7ba80925 | ||
|
833edb4d88 | ||
|
ba9a2ef74b | ||
|
215f92fabb | ||
|
0339db5604 | ||
|
ffcb42df85 | ||
|
84b5615062 | ||
|
3935b19814 | ||
|
9f219c6a08 | ||
|
904554033c | ||
|
0b87eae829 | ||
|
be9497bd75 | ||
|
9253bcdb53 | ||
|
1bdfed1d0d | ||
|
3eb84701d7 | ||
|
edc446997e | ||
|
873287e2ec | ||
|
5dee96918f | ||
|
45277ea35b | ||
|
cebe408f75 | ||
|
1950543da6 | ||
|
1dc6430ff6 | ||
|
586865823b | ||
|
7d0f7c5f99 | ||
|
92b735ffef | ||
|
a40a0f0bd6 | ||
|
c8f5653ecd |
7
.gitignore
vendored
7
.gitignore
vendored
@ -1,3 +1,6 @@
|
|||||||
.vscode/
|
# DWM Files
|
||||||
*.o
|
*.o
|
||||||
dwm
|
*.orig
|
||||||
|
dwm
|
||||||
|
dwm-msg
|
||||||
|
config.h
|
||||||
|
66
IPCClient.c
Normal file
66
IPCClient.c
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#include "IPCClient.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/epoll.h>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
IPCClient *
|
||||||
|
ipc_client_new(int fd)
|
||||||
|
{
|
||||||
|
IPCClient *c = (IPCClient *)malloc(sizeof(IPCClient));
|
||||||
|
|
||||||
|
if (c == NULL) return NULL;
|
||||||
|
|
||||||
|
// Initialize struct
|
||||||
|
memset(&c->event, 0, sizeof(struct epoll_event));
|
||||||
|
|
||||||
|
c->buffer_size = 0;
|
||||||
|
c->buffer = NULL;
|
||||||
|
c->fd = fd;
|
||||||
|
c->event.data.fd = fd;
|
||||||
|
c->next = NULL;
|
||||||
|
c->prev = NULL;
|
||||||
|
c->subscriptions = 0;
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ipc_list_add_client(IPCClientList *list, IPCClient *nc)
|
||||||
|
{
|
||||||
|
DEBUG("Adding client with fd %d to list\n", nc->fd);
|
||||||
|
|
||||||
|
if (*list == NULL) {
|
||||||
|
// List is empty, point list at first client
|
||||||
|
*list = nc;
|
||||||
|
} else {
|
||||||
|
IPCClient *c;
|
||||||
|
// Go to last client in list
|
||||||
|
for (c = *list; c && c->next; c = c->next)
|
||||||
|
;
|
||||||
|
c->next = nc;
|
||||||
|
nc->prev = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ipc_list_remove_client(IPCClientList *list, IPCClient *c)
|
||||||
|
{
|
||||||
|
IPCClient *cprev = c->prev;
|
||||||
|
IPCClient *cnext = c->next;
|
||||||
|
|
||||||
|
if (cprev != NULL) cprev->next = c->next;
|
||||||
|
if (cnext != NULL) cnext->prev = c->prev;
|
||||||
|
if (c == *list) *list = c->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPCClient *
|
||||||
|
ipc_list_get_client(IPCClientList list, int fd)
|
||||||
|
{
|
||||||
|
for (IPCClient *c = list; c; c = c->next) {
|
||||||
|
if (c->fd == fd) return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
61
IPCClient.h
Normal file
61
IPCClient.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#ifndef IPC_CLIENT_H_
|
||||||
|
#define IPC_CLIENT_H_
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/epoll.h>
|
||||||
|
|
||||||
|
typedef struct IPCClient IPCClient;
|
||||||
|
/**
|
||||||
|
* This structure contains the details of an IPC Client and pointers for a
|
||||||
|
* linked list
|
||||||
|
*/
|
||||||
|
struct IPCClient {
|
||||||
|
int fd;
|
||||||
|
int subscriptions;
|
||||||
|
|
||||||
|
char *buffer;
|
||||||
|
uint32_t buffer_size;
|
||||||
|
|
||||||
|
struct epoll_event event;
|
||||||
|
IPCClient *next;
|
||||||
|
IPCClient *prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef IPCClient *IPCClientList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate memory for new IPCClient with the specified file descriptor and
|
||||||
|
* initialize struct.
|
||||||
|
*
|
||||||
|
* @param fd File descriptor of IPC client
|
||||||
|
*
|
||||||
|
* @return Address to allocated IPCClient struct
|
||||||
|
*/
|
||||||
|
IPCClient *ipc_client_new(int fd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an IPC Client to the specified list
|
||||||
|
*
|
||||||
|
* @param list Address of the list to add the client to
|
||||||
|
* @param nc Address of the IPCClient
|
||||||
|
*/
|
||||||
|
void ipc_list_add_client(IPCClientList *list, IPCClient *nc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an IPCClient from the specified list
|
||||||
|
*
|
||||||
|
* @param list Address of the list to remove the client from
|
||||||
|
* @param c Address of the IPCClient
|
||||||
|
*/
|
||||||
|
void ipc_list_remove_client(IPCClientList *list, IPCClient *c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an IPCClient from the specified IPCClient list
|
||||||
|
*
|
||||||
|
* @param list List to remove the client from
|
||||||
|
* @param fd File descriptor of the IPCClient
|
||||||
|
*/
|
||||||
|
IPCClient *ipc_list_get_client(IPCClientList list, int fd);
|
||||||
|
|
||||||
|
#endif // IPC_CLIENT_H_
|
1
LICENSE
1
LICENSE
@ -17,7 +17,6 @@ MIT/X Consortium License
|
|||||||
© 2015-2016 Quentin Rameau <quinq@fifth.space>
|
© 2015-2016 Quentin Rameau <quinq@fifth.space>
|
||||||
© 2015-2016 Eric Pruitt <eric.pruitt@gmail.com>
|
© 2015-2016 Eric Pruitt <eric.pruitt@gmail.com>
|
||||||
© 2016-2017 Markus Teich <markus.teich@stusta.mhn.de>
|
© 2016-2017 Markus Teich <markus.teich@stusta.mhn.de>
|
||||||
© 2020 Sravan Balaji <balajsra@umich.edu>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
13
Makefile
13
Makefile
@ -6,7 +6,7 @@ include config.mk
|
|||||||
SRC = drw.c dwm.c util.c
|
SRC = drw.c dwm.c util.c
|
||||||
OBJ = ${SRC:.c=.o}
|
OBJ = ${SRC:.c=.o}
|
||||||
|
|
||||||
all: options dwm
|
all: options dwm dwm-msg
|
||||||
|
|
||||||
options:
|
options:
|
||||||
@echo dwm build options:
|
@echo dwm build options:
|
||||||
@ -25,8 +25,11 @@ config.h:
|
|||||||
dwm: ${OBJ}
|
dwm: ${OBJ}
|
||||||
${CC} -o $@ ${OBJ} ${LDFLAGS}
|
${CC} -o $@ ${OBJ} ${LDFLAGS}
|
||||||
|
|
||||||
|
dwm-msg: dwm-msg.o
|
||||||
|
${CC} -o $@ $< ${LDFLAGS}
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
|
rm -f dwm dwm-msg ${OBJ} dwm-${VERSION}.tar.gz config.h
|
||||||
|
|
||||||
dist: clean
|
dist: clean
|
||||||
mkdir -p dwm-${VERSION}
|
mkdir -p dwm-${VERSION}
|
||||||
@ -38,14 +41,16 @@ dist: clean
|
|||||||
|
|
||||||
install: all
|
install: all
|
||||||
mkdir -p ${DESTDIR}${PREFIX}/bin
|
mkdir -p ${DESTDIR}${PREFIX}/bin
|
||||||
cp -f dwm ${DESTDIR}${PREFIX}/bin
|
cp -f dwm dwmc dwm-msg ${DESTDIR}${PREFIX}/bin
|
||||||
chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
|
chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
|
||||||
|
chmod 755 ${DESTDIR}${PREFIX}/bin/dwmc
|
||||||
|
chmod 755 ${DESTDIR}${PREFIX}/bin/dwm-msg
|
||||||
mkdir -p ${DESTDIR}${MANPREFIX}/man1
|
mkdir -p ${DESTDIR}${MANPREFIX}/man1
|
||||||
sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
|
sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
|
||||||
chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1
|
chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -f ${DESTDIR}${PREFIX}/bin/dwm\
|
rm -f ${DESTDIR}${PREFIX}/bin/dwm*\
|
||||||
${DESTDIR}${MANPREFIX}/man1/dwm.1
|
${DESTDIR}${MANPREFIX}/man1/dwm.1
|
||||||
|
|
||||||
.PHONY: all options clean dist install uninstall
|
.PHONY: all options clean dist install uninstall
|
||||||
|
97
README.md
97
README.md
@ -1,79 +1,86 @@
|
|||||||
# Sravan's dwm - dynamic window manager
|
# dwm - dynamic window manager
|
||||||
|
|
||||||
[dwm](https://dwm.suckless.org/) is an extremely fast, small, and dynamic window manager for X.
|
Sravan's custom build of dwm. Original dwm build by suckless team found here: [https://dwm.suckless.org/](https://dwm.suckless.org/)
|
||||||
This is Sravan's fork of dwm with patches and custom modifications.
|
Choice of patches heavily inspired by [Palmdrop's custom build of dwm](https://github.com/palmdrop/dwm).
|
||||||
|
|
||||||
## dwm Information
|
## Requirements
|
||||||
|
|
||||||
### Requirements
|
|
||||||
|
|
||||||
In order to build dwm you need the Xlib header files.
|
In order to build dwm you need the Xlib header files.
|
||||||
|
|
||||||
### Installation
|
## Installation
|
||||||
|
|
||||||
Edit config.mk to match your local setup (dwm is installed into
|
Edit [config.mk](config.mk) to match your local setup (dwm is installed into
|
||||||
the /usr/local namespace by default).
|
the /usr/local namespace by default).
|
||||||
|
|
||||||
Afterwards enter the following command to build and install dwm (if
|
Afterwards enter the following command to build and install dwm (if
|
||||||
necessary as root):
|
necessary as root):
|
||||||
|
|
||||||
make clean install
|
```
|
||||||
|
make clean install
|
||||||
|
```
|
||||||
|
|
||||||
### Running dwm
|
## Running dwm
|
||||||
|
|
||||||
Add the following line to your .xinitrc to start dwm using startx:
|
Add the following line to your .xinitrc to start dwm using startx:
|
||||||
|
|
||||||
exec dwm
|
```
|
||||||
|
exec dwm
|
||||||
|
```
|
||||||
|
|
||||||
In order to connect dwm to a specific display, make sure that
|
In order to connect dwm to a specific display, make sure that
|
||||||
the DISPLAY environment variable is set correctly, e.g.:
|
the DISPLAY environment variable is set correctly, e.g.:
|
||||||
|
|
||||||
DISPLAY=foo.bar:1 exec dwm
|
```
|
||||||
|
DISPLAY=foo.bar:1 exec dwm
|
||||||
|
```
|
||||||
|
|
||||||
(This will start dwm on display :1 of the host foo.bar.)
|
(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
|
In order to display status info in the bar, you can do something
|
||||||
like this in your .xinitrc:
|
like this in your .xinitrc:
|
||||||
|
|
||||||
while xsetroot -name "`date` `uptime | sed 's/.*,//'`"
|
```
|
||||||
do
|
while xsetroot -name "`date` `uptime | sed 's/.*,//'`"
|
||||||
sleep 1
|
do
|
||||||
done &
|
sleep 1
|
||||||
exec dwm
|
done &
|
||||||
|
exec dwm
|
||||||
|
```
|
||||||
|
|
||||||
### Configuration
|
## Configuration
|
||||||
|
|
||||||
The configuration of dwm is done by creating a custom config.h
|
The configuration of dwm is done by creating a custom config.h
|
||||||
and (re)compiling the source code.
|
and (re)compiling the source code.
|
||||||
|
|
||||||
## Personal Modifications
|
## Patches
|
||||||
|
|
||||||
### Patches
|
Most patches can be found on the suckless website: [https://dwm.suckless.org/patches/](https://dwm.suckless.org/patches/)
|
||||||
|
|
||||||
* [autostart](https://dwm.suckless.org/patches/autostart/)
|
* [actualfullscreen](https://dwm.suckless.org/patches/actualfullscreen/) - Actually toggle fullscreen for a window, instead of toggling the status bar and the monocle layout
|
||||||
* [centeredmaster](https://dwm.suckless.org/patches/centeredmaster/)
|
* [alwaysfullscreen](https://dwm.suckless.org/patches/alwaysfullscreen/) - Do not allow the focus to drift from the active fullscreen client when using focusstack()
|
||||||
* [combo](https://dwm.suckless.org/patches/combo/)
|
* [anybar](https://github.com/mihirlad55/dwm-anybar) (Polybar Tray Fix Version) - Enables dwm to manage external status bars such as lemonbar and polybar
|
||||||
* [cyclelayouts](https://dwm.suckless.org/patches/cyclelayouts/)
|
* [aspectresize](https://dwm.suckless.org/patches/aspectresize/) - Allows you to resize a window while maintaining aspect ratio
|
||||||
* [gridmode](https://dwm.suckless.org/patches/gridmode/)
|
* [attachbelow](https://dwm.suckless.org/patches/attachbelow/) (Toggleable) - Make new clients attach below the selected client, instead of always becoming the new master
|
||||||
* [movestack](https://dwm.suckless.org/patches/movestack/)
|
* [autoresize](https://dwm.suckless.org/patches/autoresize/) - Windows that are not visible when requesting a resize/move will get resized/moved
|
||||||
* [restartsig](https://dwm.suckless.org/patches/restartsig/)
|
* [center](https://dwm.suckless.org/patches/center/) - Add an `iscentered` rule to automatically center clients on the current monitor
|
||||||
* [ru_gaps](https://dwm.suckless.org/patches/ru_gaps/)
|
* [cfacts](https://dwm.suckless.org/patches/cfacts/) - Assign different weights to clients in their respective stack in tiled layout
|
||||||
* [systray](https://dwm.suckless.org/patches/systray/)
|
* [cfacts-vanitygaps](https://github.com/bakkeby/patches/blob/master/dwm/dwm-cfacts-vanitygaps-6.2.diff) - Vanity gaps patch compatible with cfacts patch
|
||||||
|
* [combo](https://dwm.suckless.org/patches/combo/) - Select multiple tags for tag or view by pressing all the right keys as a combo
|
||||||
|
* [cool autostart](https://dwm.suckless.org/patches/cool_autostart/) - Execute commands from `autostart` array in `config.h` on startup and kill processes upon dwm exit
|
||||||
|
* [cyclelayouts](https://dwm.suckless.org/patches/cyclelayouts/) - Cycle through all available layouts
|
||||||
|
* [dwmc](https://dwm.suckless.org/patches/dwmc/) - Simple dwmc client using a fork of [fsignal](https://dwm.suckless.org/patches/fsignal/) to communicate with dwm
|
||||||
|
* [fixborders](https://dwm.suckless.org/patches/alpha/) - Make borders opaque
|
||||||
|
* [ipc](https://github.com/mihirlad55/dwm-ipc) - Allows third party programs (e.g. polybar) to query window manager for information
|
||||||
|
* [movestack](https://dwm.suckless.org/patches/movestack/) - Move clients around in the stack and swap them with the master
|
||||||
|
* [noborder](https://dwm.suckless.org/patches/noborder/) (Floating Fix) - Remove the border when there is only one window visible
|
||||||
|
* [swallow](https://dwm.suckless.org/patches/swallow/) - Programs opened from terminal will "swallow" the terminal
|
||||||
|
* [unfloatvisible](https://dwm.suckless.org/patches/unfloatvisible/) - Resets `isfloating` on any visible windows that have it set
|
||||||
|
* [xresources](https://dwm.suckless.org/patches/xresources/) - Allows dwm settings (e.g. colors) to be set in Xresources
|
||||||
|
|
||||||
### Modifications
|
## Polybar
|
||||||
|
|
||||||
* Change mod key to super key (windows key)
|
The anybar and ipc patches above allow dwm to use an external status bar.
|
||||||
* Change terminal from st to alacritty
|
I am using polybar. My config can be found [here](https://github.com/balajsra/polybar).
|
||||||
* Change colors to follow [Dracula](https://draculatheme.com) theme
|
|
||||||
* Increase border to 3 pixels
|
* [Polybar DWM Module](https://github.com/mihirlad55/polybar-dwm-module)
|
||||||
* Set default gap size to 10 pixels
|
* [Polybar](https://github.com/polybar/polybar)
|
||||||
* Change tags to be [Font Awesome](https://fontawesome.com) icons
|
|
||||||
* Run programs and processes on autostart
|
|
||||||
* [Pulse Audio Volume Control](https://gist.github.com/palopezv/efd34059af6126ad970940bcc6a90f2e)
|
|
||||||
* Media Play/Pause, Prev, and Next Keybindings via [Playerctl](https://github.com/altdesktop/playerctl)
|
|
||||||
* Arch Community Repo: [playerctl](https://www.archlinux.org/packages/community/x86_64/playerctl/)
|
|
||||||
* Use [light-locker](https://github.com/the-cavalry/light-locker) to lock screen with [LightDM](https://github.com/canonical/lightdm)
|
|
||||||
* Arch Community Repo: [lightdm](https://www.archlinux.org/packages/extra/x86_64/lightdm/)
|
|
||||||
* Arch Community Repo: [light-locker](https://www.archlinux.org/packages/community/x86_64/light-locker/)
|
|
||||||
* Brightness Increase and Decrease Keybindings via [acpilight](https://gitlab.com/wavexx/acpilight)
|
|
||||||
* Arch Community Repo: [acpilight](https://www.archlinux.org/packages/community/any/acpilight/)
|
|
||||||
|
53
autoquit.sh
53
autoquit.sh
@ -1,53 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
########################
|
|
||||||
# Startup Applications #
|
|
||||||
########################
|
|
||||||
# List of applications to kill on exit
|
|
||||||
declare -a applications_array=(\
|
|
||||||
# System Tray Applications
|
|
||||||
"volctl" \ # PulseAudio Volume Control
|
|
||||||
"nyrna" \ # Nyrna Application Suspend
|
|
||||||
"blueman-tray" \ # Blueman Bluetooth Manager
|
|
||||||
"nm-applet" \ # Network Manager Applet
|
|
||||||
"kdeconnect-indi" \ # KDE Connect
|
|
||||||
"flameshot" \ # Flameshot Screenshot Tool
|
|
||||||
"redshift-gtk" \ # Redshift Blue Light Filter
|
|
||||||
# Background Processes
|
|
||||||
"picom" \ # Picom Compositor
|
|
||||||
"xfce4-notifyd" \ # Xfce Notification Daemon
|
|
||||||
"greenclip" \ # Greenclip Clipboard Manager
|
|
||||||
"redshift" \ # Redshift Blue Light Filter
|
|
||||||
"polkit-gnome-au" \ # GNOME Polkit Authentication Agent
|
|
||||||
"slstatus" \ # slstatus status bar
|
|
||||||
"light-locker" \ # LightDM Locker
|
|
||||||
# Hardware Driver Applications
|
|
||||||
"solaar" \ # Logitech Mouse Driver
|
|
||||||
"polychromatic-t" \ # Razer Keyboard Customization
|
|
||||||
"optimus-manager" \ # Optimus Manager Qt
|
|
||||||
)
|
|
||||||
|
|
||||||
# Kill applications
|
|
||||||
for i in "${applications_array[@]}"
|
|
||||||
do
|
|
||||||
pkill -9 $i &
|
|
||||||
done
|
|
||||||
|
|
||||||
#####################
|
|
||||||
# Cloud Drive Rsync #
|
|
||||||
#####################
|
|
||||||
# Local cloud storage directory
|
|
||||||
local_clone_dir="$HOME/Cloud"
|
|
||||||
|
|
||||||
# List of remotes as defined in rclone
|
|
||||||
declare -a remote_array=(\
|
|
||||||
"OneDrive - Personal" \
|
|
||||||
"Google Drive - Personal" \
|
|
||||||
)
|
|
||||||
|
|
||||||
# Unmount Remotes
|
|
||||||
for i in "${remote_array[@]}"
|
|
||||||
do
|
|
||||||
local_path="$local_clone_dir"/"$i"
|
|
||||||
fusermount -u "$local_path" &
|
|
||||||
done
|
|
62
autostart.sh
62
autostart.sh
@ -1,62 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
########################
|
|
||||||
# Startup Applications #
|
|
||||||
########################
|
|
||||||
# List of applications to run on start
|
|
||||||
declare -a applications_array=(\
|
|
||||||
# System Restore Processes
|
|
||||||
"bash /home/sravan/.screenlayout/default-screen-layout.sh" \ # Restore default screen layout
|
|
||||||
"nitrogen --restore" \ # Restore wallpaper
|
|
||||||
# System Tray Applications
|
|
||||||
"volctl" \ # PulseAudio Volume Control
|
|
||||||
"nyrna" \ # Nyrna Application Suspend
|
|
||||||
"blueman-tray" \ # Blueman Bluetooth Manager
|
|
||||||
"nm-applet" \ # Network Manager Applet
|
|
||||||
"kdeconnect-indicator" \ # KDE Connect
|
|
||||||
"flameshot" \ # Flameshot Screenshot Tool
|
|
||||||
# Background Processes
|
|
||||||
"picom --config /home/sravan/.config/picom/picom.conf" \ # Picom Compositor
|
|
||||||
"/usr/lib/xfce4/notifyd/xfce4-notifyd" \ # Xfce Notification Daemon
|
|
||||||
"greenclip daemon" \ # Greenclip Clipboard Manager
|
|
||||||
"redshift -x" \ # Reset redshift display gamma
|
|
||||||
"redshift-gtk" \ # Redshift Blue Light Filter
|
|
||||||
"/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1" \ # GNOME Polkit Authentication Agent
|
|
||||||
"slstatus" \ # slstatus status bar
|
|
||||||
"light-locker --lock-on-suspend --lock-on-lid" \ # LightDM Locker
|
|
||||||
# Hardware Driver Applications
|
|
||||||
"solaar --window=hide" \ # Logitech Mouse Driver
|
|
||||||
"polychromatic-tray-applet" \ # Razer Keyboard Customization
|
|
||||||
"optimus-manager-qt" \ # Optimus Manager Qt
|
|
||||||
)
|
|
||||||
|
|
||||||
# Run applications (ignore if they don't exist)
|
|
||||||
for i in "${applications_array[@]}"
|
|
||||||
do
|
|
||||||
if ! command -v $i > /dev/null
|
|
||||||
then
|
|
||||||
do_nothing() { :; }
|
|
||||||
else
|
|
||||||
$i &
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
#####################
|
|
||||||
# Cloud Drive Rsync #
|
|
||||||
#####################
|
|
||||||
# Local cloud storage directory
|
|
||||||
local_clone_dir="$HOME/Cloud"
|
|
||||||
|
|
||||||
# List of remotes as defined in rclone
|
|
||||||
declare -a remote_array=(\
|
|
||||||
"OneDrive - Personal" \
|
|
||||||
"Google Drive - Personal" \
|
|
||||||
)
|
|
||||||
|
|
||||||
# Mount Remotes
|
|
||||||
for i in "${remote_array[@]}"
|
|
||||||
do
|
|
||||||
local_path="$local_clone_dir"/"$i"
|
|
||||||
mkdir -p "$local_path"
|
|
||||||
rclone mount "$i": "$local_path" &
|
|
||||||
done
|
|
353
config.def.h
353
config.def.h
@ -1,99 +1,246 @@
|
|||||||
/* See LICENSE file for copyright and license details. */
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
|
||||||
/* appearance */
|
/* appearance */
|
||||||
static const unsigned int borderpx = 1; /* border pixel of windows */
|
static unsigned int borderpx = 2; /* border pixel of windows */
|
||||||
static const unsigned int snap = 32; /* snap pixel */
|
static const unsigned int snap = 32; /* snap pixel */
|
||||||
|
static unsigned int gappih = 20; /* horiz inner gap between windows */
|
||||||
|
static unsigned int gappiv = 20; /* vert inner gap between windows */
|
||||||
|
static unsigned int gappoh = 10; /* horiz outer gap between windows and screen edge */
|
||||||
|
static unsigned int gappov = 10; /* vert outer gap between windows and screen edge */
|
||||||
|
static const int noborder = 0; /* 1 means no border when there is only one window */
|
||||||
|
static const int swallowfloating = 0; /* 1 means swallow floating windows by default */
|
||||||
|
static int smartgaps = 0; /* 1 means no outer gap when there is only one window */
|
||||||
static const int showbar = 1; /* 0 means no bar */
|
static const int showbar = 1; /* 0 means no bar */
|
||||||
static const int topbar = 1; /* 0 means bottom bar */
|
static const int topbar = 1; /* 0 means bottom bar */
|
||||||
static const char *fonts[] = { "monospace:size=10" };
|
static const int usealtbar = 1; /* 1 means use non-dwm status bar */
|
||||||
static const char dmenufont[] = "monospace:size=10";
|
static const char *altbarclass = "Polybar"; /* Alternate bar class name */
|
||||||
static const char col_gray1[] = "#222222";
|
static const char *alttrayname = "tray"; /* Polybar tray instance name */
|
||||||
static const char col_gray2[] = "#444444";
|
static const char *altbarcmd = "$HOME/.config/polybar/launch.sh"; /* Alternate bar launch command */
|
||||||
static const char col_gray3[] = "#bbbbbb";
|
static const char *fonts[] = { "NotoSans Nerd Font:size=10" };
|
||||||
static const char col_gray4[] = "#eeeeee";
|
static char normbgcolor[] = "#222222"; /* background color */
|
||||||
static const char col_cyan[] = "#005577";
|
static char normbordercolor[] = "#444444"; /* inactive window border color */
|
||||||
static const char *colors[][3] = {
|
static char normfgcolor[] = "#bbbbbb"; /* font color */
|
||||||
/* fg bg border */
|
static char selfgcolor[] = "#eeeeee"; /* current tag and current window font color */
|
||||||
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
|
static char selbordercolor[] = "#005577"; /* Top bar second color and active window border color */
|
||||||
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
|
static char selbgcolor[] = "#005577"; /* Top bar second color and active window border color */
|
||||||
|
static char *colors[][3] = {
|
||||||
|
/* fg bg border */
|
||||||
|
[SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor },
|
||||||
|
[SchemeSel] = { selfgcolor, selbgcolor, selbordercolor },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *const autostart[] = {
|
||||||
|
// System Restore Processes
|
||||||
|
"bash", "/home/sravan/.screenlayout/default-screen-layout.sh", NULL, // Restore default screen layout
|
||||||
|
"nitrogen", "--restore", NULL, // Restore wallpaper
|
||||||
|
"numlockx", "on", NULL, // NumLock on by default
|
||||||
|
// System Tray Applications
|
||||||
|
"volctl", NULL, // PulseAudio Volume Control
|
||||||
|
"nyrna", NULL, // Nyrna Application Suspend
|
||||||
|
"blueman-applet", NULL, // Blueman Bluetooth Manager
|
||||||
|
"nm-applet", NULL, // Network Manager Applet
|
||||||
|
"kdeconnect-indicator", NULL, // KDE Connect
|
||||||
|
"flameshot", NULL, // Flameshot Screenshot Tool
|
||||||
|
"xfce4-power-manager", NULL, // XFCE4 Power Manager
|
||||||
|
// Background Processes
|
||||||
|
"bash", "/home/sravan/.config/picom/toggle_picom.sh", NULL, // Picom Compositor
|
||||||
|
"bash", "/home/sravan/.config/dunst/launch_dunst.sh", NULL, // Dunst Notification Daemon
|
||||||
|
"greenclip", "daemon", NULL, // Greenclip Clipboard Manager
|
||||||
|
"redshift", "-x", NULL, // Reset redshift display gamma
|
||||||
|
"redshift-gtk", NULL, // Redshift Blue Light Filter
|
||||||
|
"/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1", NULL, // GNOME Polkit Authentication Agent
|
||||||
|
"xss-lock", "-l", "--", "multilockscreen", "--lock", NULL, // Session lock handler
|
||||||
|
// Hardware Driver Applications
|
||||||
|
"solaar", "--window=hide", NULL, // Logitech Mouse Driver
|
||||||
|
"openrgb", "--startminimized", NULL, // OpenRGB
|
||||||
|
"optimus-manager-qt", NULL, // Optimus Manager Qt
|
||||||
|
NULL /* terminate */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* tagging */
|
/* tagging */
|
||||||
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
|
static const char *tags[] = { " ₁", "龎 ₂", " ₃", " ₄", "爵 ₅", " ₆", " ₇", " ₈", " ₉" };
|
||||||
|
|
||||||
static const Rule rules[] = {
|
static const Rule rules[] = {
|
||||||
/* xprop(1):
|
/* xprop(1):
|
||||||
* WM_CLASS(STRING) = instance, class
|
* WM_CLASS(STRING) = instance, class
|
||||||
* WM_NAME(STRING) = title
|
* WM_NAME(STRING) = title
|
||||||
*/
|
*/
|
||||||
/* class instance title tags mask isfloating monitor */
|
/* class instance title tags mask isfloating isterminal noswallow monitor */
|
||||||
{ "Gimp", NULL, NULL, 0, 1, -1 },
|
{ NULL, NULL, "Origin", 0, 1, 0, 0, -1 },
|
||||||
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
|
{ "kitty", NULL, NULL, 0, 0, 0, 1, -1 },
|
||||||
|
{ NULL, NULL, "Event Tester", 0, 0, 0, 1, -1 }, /* xev */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* layout(s) */
|
/* layout(s) */
|
||||||
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
|
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 nmaster = 1; /* number of clients in master area */
|
||||||
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
|
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
|
||||||
|
static int attachbelow = 1; /* 1 means attach after the currently active window */
|
||||||
|
|
||||||
|
#define FORCE_VSPLIT 1 /* nrowgrid layout: force two clients to always split vertically */
|
||||||
|
#include "vanitygaps.c"
|
||||||
|
|
||||||
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 */
|
|
||||||
{ "[M]", monocle },
|
{ "[M]", monocle },
|
||||||
|
{ "[@]", spiral },
|
||||||
|
{ "[\\]", dwindle },
|
||||||
|
{ "H[]", deck },
|
||||||
|
{ "TTT", bstack },
|
||||||
|
{ "===", bstackhoriz },
|
||||||
|
{ "HHH", grid },
|
||||||
|
{ "###", nrowgrid },
|
||||||
|
{ "---", horizgrid },
|
||||||
|
{ ":::", gaplessgrid },
|
||||||
|
{ "|M|", centeredmaster },
|
||||||
|
{ ">M>", centeredfloatingmaster },
|
||||||
|
{ "><>", NULL }, /* no layout function means floating behavior */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* key definitions */
|
/* key definitions */
|
||||||
#define MODKEY Mod1Mask
|
#define MODKEY Mod4Mask /* Mod1Mask = Alt, Mod4Mask = Super */
|
||||||
#define TAGKEYS(KEY,TAG) \
|
#define TAGKEYS(KEY,TAG) \
|
||||||
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
|
{ MODKEY, KEY, comboview, {.ui = 1 << TAG} }, \
|
||||||
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
|
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
|
||||||
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
|
{ MODKEY|ShiftMask, KEY, combotag, {.ui = 1 << TAG} }, \
|
||||||
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
|
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
|
||||||
|
|
||||||
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
|
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
|
||||||
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
||||||
|
|
||||||
/* commands */
|
/* commands */
|
||||||
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
|
static const char *rofiruncmd[] = { "rofi", "-show", "drun", NULL };
|
||||||
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 *roficlipcmd[] = { "rofi", "-show", "clipboard", NULL };
|
||||||
static const char *termcmd[] = { "st", NULL };
|
static const char *lockcmd[] = { "loginctl", "lock-session", NULL };
|
||||||
|
static const char *sleepcmd[] = { "systemctl", "suspend", NULL };
|
||||||
|
static const char *termcmd[] = { "kitty", NULL };
|
||||||
|
static const char *upvolcmd[] = { "/usr/bin/pactl", "set-sink-volume", "@DEFAULT_SINK@", "+1%", NULL };
|
||||||
|
static const char *downvolcmd[] = { "/usr/bin/pactl", "set-sink-volume", "@DEFAULT_SINK@", "-1%", NULL };
|
||||||
|
static const char *mutevolcmd[] = { "/usr/bin/pactl", "set-sink-mute", "@DEFAULT_SINK@", "toggle", NULL };
|
||||||
|
static const char *playerplaypausecmd[] = { "playerctl", "--player=playerctld", "play-pause", NULL };
|
||||||
|
static const char *playernextcmd[] = { "playerctl", "--player=playerctld", "next", NULL };
|
||||||
|
static const char *playerprevcmd[] = { "playerctl", "--player=playerctld", "previous", NULL };
|
||||||
|
static const char *playershiftcmd[] = { "playerctld", "shift", NULL};
|
||||||
|
static const char *flameshotcmd[] = { "flameshot", "gui", NULL };
|
||||||
|
static const char *notifycontextcmd[] = { "dunstctl", "context", NULL };
|
||||||
|
static const char *notifyhistorycmd[] = { "dunstctl", "history-pop", NULL };
|
||||||
|
static const char *notifyclosecmd[] = { "dunstctl", "close", NULL };
|
||||||
|
static const char *notifytogglecmd[] = { "dunstctl", "set-paused", "toggle", NULL };
|
||||||
|
static const char *compositortogglecmd[] = { "/bin/bash", "/home/sravan/.config/picom/toggle_picom.sh", NULL, };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Xresources preferences to load at startup
|
||||||
|
*/
|
||||||
|
ResourcePref resources[] = {
|
||||||
|
{ "normbgcolor", STRING, &normbgcolor },
|
||||||
|
{ "normbordercolor", STRING, &normbordercolor },
|
||||||
|
{ "normfgcolor", STRING, &normfgcolor },
|
||||||
|
{ "selbgcolor", STRING, &selbgcolor },
|
||||||
|
{ "selbordercolor", STRING, &selbordercolor },
|
||||||
|
{ "selfgcolor", STRING, &selfgcolor },
|
||||||
|
{ "borderpx", INTEGER, &borderpx },
|
||||||
|
{ "gappih", INTEGER, &gappih },
|
||||||
|
{ "gappiv", INTEGER, &gappiv },
|
||||||
|
{ "gappoh", INTEGER, &gappoh },
|
||||||
|
{ "gappov", INTEGER, &gappov },
|
||||||
|
// { "snap", INTEGER, &snap },
|
||||||
|
// { "showbar", INTEGER, &showbar },
|
||||||
|
// { "topbar", INTEGER, &topbar },
|
||||||
|
// { "nmaster", INTEGER, &nmaster },
|
||||||
|
// { "resizehints", INTEGER, &resizehints },
|
||||||
|
// { "mfact", FLOAT, &mfact },
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "movestack.c"
|
||||||
|
#include "unfloat.c"
|
||||||
|
#include <X11/XF86keysym.h>
|
||||||
static Key keys[] = {
|
static Key keys[] = {
|
||||||
/* modifier key function argument */
|
/* modifier key function argument */
|
||||||
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
|
{ MODKEY, XK_p, spawn, {.v = rofiruncmd} },
|
||||||
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
|
{ MODKEY, XK_c, spawn, {.v = roficlipcmd} },
|
||||||
{ MODKEY, XK_b, togglebar, {0} },
|
{ MODKEY|ControlMask|ShiftMask, XK_l, spawn, {.v = lockcmd} },
|
||||||
{ MODKEY, XK_j, focusstack, {.i = +1 } },
|
{ MODKEY|ControlMask|ShiftMask, XK_s, spawn, {.v = sleepcmd} },
|
||||||
{ MODKEY, XK_k, focusstack, {.i = -1 } },
|
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd} },
|
||||||
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
|
{ MODKEY, XK_n, spawn, {.v = notifycontextcmd} },
|
||||||
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
|
{ MODKEY|ShiftMask, XK_n, spawn, {.v = notifyhistorycmd} },
|
||||||
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
|
{ MODKEY|ControlMask, XK_n, spawn, {.v = notifyclosecmd} },
|
||||||
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
|
{ MODKEY|ControlMask|ShiftMask, XK_n, spawn, {.v = notifytogglecmd} },
|
||||||
{ MODKEY, XK_Return, zoom, {0} },
|
{ MODKEY|ControlMask|ShiftMask, XK_Escape, spawn, {.v = compositortogglecmd} },
|
||||||
{ MODKEY, XK_Tab, view, {0} },
|
{ MODKEY, XK_b, togglebar, {0} },
|
||||||
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
|
{ MODKEY, XK_j, focusstack, {.i = +1 } },
|
||||||
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
{ MODKEY, XK_k, focusstack, {.i = -1 } },
|
||||||
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
|
{ MODKEY, XK_i, incnmaster, {.i = +1 } },
|
||||||
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
|
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
|
||||||
{ MODKEY, XK_space, setlayout, {0} },
|
{ MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } },
|
||||||
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
{ MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } },
|
||||||
{ MODKEY, XK_0, view, {.ui = ~0 } },
|
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
|
||||||
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
|
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
|
||||||
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
|
{ MODKEY|ShiftMask, XK_h, setcfact, {.f = +0.25} },
|
||||||
{ MODKEY, XK_period, focusmon, {.i = +1 } },
|
{ MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} },
|
||||||
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
|
{ MODKEY|ShiftMask, XK_o, setcfact, {.f = 0.00} },
|
||||||
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
|
{ MODKEY, XK_Return, zoom, {0} },
|
||||||
TAGKEYS( XK_1, 0)
|
{ MODKEY|ControlMask, XK_u, incrgaps, {.i = +1 } },
|
||||||
TAGKEYS( XK_2, 1)
|
{ MODKEY|ControlMask|ShiftMask, XK_u, incrgaps, {.i = -1 } },
|
||||||
TAGKEYS( XK_3, 2)
|
{ MODKEY|ControlMask, XK_i, incrigaps, {.i = +1 } },
|
||||||
TAGKEYS( XK_4, 3)
|
{ MODKEY|ControlMask|ShiftMask, XK_i, incrigaps, {.i = -1 } },
|
||||||
TAGKEYS( XK_5, 4)
|
{ MODKEY|ControlMask, XK_o, incrogaps, {.i = +1 } },
|
||||||
TAGKEYS( XK_6, 5)
|
{ MODKEY|ControlMask|ShiftMask, XK_o, incrogaps, {.i = -1 } },
|
||||||
TAGKEYS( XK_7, 6)
|
{ MODKEY|ControlMask, XK_6, incrihgaps, {.i = +1 } },
|
||||||
TAGKEYS( XK_8, 7)
|
{ MODKEY|ControlMask|ShiftMask, XK_6, incrihgaps, {.i = -1 } },
|
||||||
TAGKEYS( XK_9, 8)
|
{ MODKEY|ControlMask, XK_7, incrivgaps, {.i = +1 } },
|
||||||
{ MODKEY|ShiftMask, XK_q, quit, {0} },
|
{ MODKEY|ControlMask|ShiftMask, XK_7, incrivgaps, {.i = -1 } },
|
||||||
|
{ MODKEY|ControlMask, XK_8, incrohgaps, {.i = +1 } },
|
||||||
|
{ MODKEY|ControlMask|ShiftMask, XK_8, incrohgaps, {.i = -1 } },
|
||||||
|
{ MODKEY|ControlMask, XK_9, incrovgaps, {.i = +1 } },
|
||||||
|
{ MODKEY|ControlMask|ShiftMask, XK_9, incrovgaps, {.i = -1 } },
|
||||||
|
{ MODKEY|ControlMask, XK_0, togglegaps, {0} },
|
||||||
|
{ MODKEY|ControlMask|ShiftMask, XK_0, defaultgaps, {0} },
|
||||||
|
{ MODKEY, XK_Tab, comboview, {0} },
|
||||||
|
{ MODKEY|ControlMask, XK_j, aspectresize, {.i = +24} },
|
||||||
|
{ MODKEY|ControlMask, XK_k, aspectresize, {.i = -24} },
|
||||||
|
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
|
||||||
|
{ MODKEY|ControlMask|ShiftMask, XK_c, spawn, SHCMD("kill -SEGV ""\"$(xprop | grep PID| awk '{print $3}')""\"") },
|
||||||
|
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
||||||
|
{ MODKEY|ShiftMask, XK_t, unfloatvisible, {.v = &layouts[0]} },
|
||||||
|
{ MODKEY, XK_m, setlayout, {.v = &layouts[1]} },
|
||||||
|
{ MODKEY|ShiftMask, XK_m, unfloatvisible, {.v = &layouts[1]} },
|
||||||
|
{ MODKEY, XK_g, setlayout, {.v = &layouts[7]} },
|
||||||
|
{ MODKEY|ShiftMask, XK_g, unfloatvisible, {.v = &layouts[7]} },
|
||||||
|
{ MODKEY, XK_u, setlayout, {.v = &layouts[11]} },
|
||||||
|
{ MODKEY|ShiftMask, XK_u, unfloatvisible, {.v = &layouts[11]} },
|
||||||
|
{ MODKEY, XK_f, setlayout, {.v = &layouts[13]} },
|
||||||
|
{ MODKEY|ControlMask, XK_comma, cyclelayout, {.i = -1 } },
|
||||||
|
{ MODKEY|ControlMask, XK_period, cyclelayout, {.i = +1 } },
|
||||||
|
{ MODKEY, XK_space, setlayout, {0} },
|
||||||
|
{ MODKEY|ShiftMask, XK_space, unfloatvisible, {0} },
|
||||||
|
{ MODKEY|ControlMask, XK_space, togglefloating, {0} },
|
||||||
|
{ MODKEY|ShiftMask, XK_f, togglefullscr, {0} },
|
||||||
|
{ MODKEY|ShiftMask, XK_Tab, toggleAttachBelow, {0} },
|
||||||
|
{ MODKEY, XK_0, comboview, {.ui = ~0 } },
|
||||||
|
{ MODKEY|ShiftMask, XK_0, combotag, {.ui = ~0 } },
|
||||||
|
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
|
||||||
|
{ MODKEY, XK_period, focusmon, {.i = +1 } },
|
||||||
|
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
|
||||||
|
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
|
||||||
|
{ MODKEY|ControlMask|ShiftMask, XK_Tab, spawn, {.v = playershiftcmd} },
|
||||||
|
{ 0, XF86XK_AudioLowerVolume, spawn, {.v = downvolcmd} },
|
||||||
|
{ 0, XF86XK_AudioMute, spawn, {.v = mutevolcmd} },
|
||||||
|
{ 0, XF86XK_AudioRaiseVolume, spawn, {.v = upvolcmd} },
|
||||||
|
{ 0, XF86XK_AudioPlay, spawn, {.v = playerplaypausecmd} },
|
||||||
|
{ 0, XF86XK_AudioNext, spawn, {.v = playernextcmd} },
|
||||||
|
{ 0, XF86XK_AudioPrev, spawn, {.v = playerprevcmd} },
|
||||||
|
{ 0, XK_Print, spawn, {.v = flameshotcmd} },
|
||||||
|
TAGKEYS( XK_1, 0)
|
||||||
|
TAGKEYS( XK_2, 1)
|
||||||
|
TAGKEYS( XK_3, 2)
|
||||||
|
TAGKEYS( XK_4, 3)
|
||||||
|
TAGKEYS( XK_5, 4)
|
||||||
|
TAGKEYS( XK_6, 5)
|
||||||
|
TAGKEYS( XK_7, 6)
|
||||||
|
TAGKEYS( XK_8, 7)
|
||||||
|
TAGKEYS( XK_9, 8)
|
||||||
|
{ MODKEY|ControlMask|ShiftMask, XK_q, quit, {0} },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* button definitions */
|
/* button definitions */
|
||||||
@ -107,9 +254,97 @@ static Button buttons[] = {
|
|||||||
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
|
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
|
||||||
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
|
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
|
||||||
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
|
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
|
||||||
{ ClkTagBar, 0, Button1, view, {0} },
|
{ ClkTagBar, 0, Button1, comboview, {0} },
|
||||||
{ ClkTagBar, 0, Button3, toggleview, {0} },
|
{ ClkTagBar, 0, Button3, toggleview, {0} },
|
||||||
{ ClkTagBar, MODKEY, Button1, tag, {0} },
|
{ ClkTagBar, MODKEY, Button1, combotag, {0} },
|
||||||
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
|
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *ipcsockpath = "/tmp/dwm.sock";
|
||||||
|
static IPCCommand ipccommands[] = {
|
||||||
|
IPCCOMMAND( view, 1, {ARG_TYPE_UINT} ),
|
||||||
|
IPCCOMMAND( toggleview, 1, {ARG_TYPE_UINT} ),
|
||||||
|
IPCCOMMAND( tag, 1, {ARG_TYPE_UINT} ),
|
||||||
|
IPCCOMMAND( toggletag, 1, {ARG_TYPE_UINT} ),
|
||||||
|
IPCCOMMAND( tagmon, 1, {ARG_TYPE_UINT} ),
|
||||||
|
IPCCOMMAND( focusmon, 1, {ARG_TYPE_SINT} ),
|
||||||
|
IPCCOMMAND( focusstack, 1, {ARG_TYPE_SINT} ),
|
||||||
|
IPCCOMMAND( zoom, 1, {ARG_TYPE_NONE} ),
|
||||||
|
IPCCOMMAND( incnmaster, 1, {ARG_TYPE_SINT} ),
|
||||||
|
IPCCOMMAND( killclient, 1, {ARG_TYPE_SINT} ),
|
||||||
|
IPCCOMMAND( togglefloating, 1, {ARG_TYPE_NONE} ),
|
||||||
|
IPCCOMMAND( setmfact, 1, {ARG_TYPE_FLOAT} ),
|
||||||
|
IPCCOMMAND( setlayoutsafe, 1, {ARG_TYPE_PTR} ),
|
||||||
|
IPCCOMMAND( quit, 1, {ARG_TYPE_NONE} )
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
setlayoutex(const Arg *arg)
|
||||||
|
{
|
||||||
|
setlayout(&((Arg) { .v = &layouts[arg->i] }));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
viewex(const Arg *arg)
|
||||||
|
{
|
||||||
|
view(&((Arg) { .ui = 1 << arg->ui }));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
viewall(const Arg *arg)
|
||||||
|
{
|
||||||
|
view(&((Arg){.ui = ~0}));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
toggleviewex(const Arg *arg)
|
||||||
|
{
|
||||||
|
toggleview(&((Arg) { .ui = 1 << arg->ui }));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tagex(const Arg *arg)
|
||||||
|
{
|
||||||
|
tag(&((Arg) { .ui = 1 << arg->ui }));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
toggletagex(const Arg *arg)
|
||||||
|
{
|
||||||
|
toggletag(&((Arg) { .ui = 1 << arg->ui }));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tagall(const Arg *arg)
|
||||||
|
{
|
||||||
|
tag(&((Arg){.ui = ~0}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* signal definitions */
|
||||||
|
/* signum must be greater than 0 */
|
||||||
|
/* trigger signals using `xsetroot -name "fsignal:<signame> [<type> <value>]"` */
|
||||||
|
static Signal signals[] = {
|
||||||
|
/* signum function */
|
||||||
|
{ "focusstack", focusstack },
|
||||||
|
{ "setmfact", setmfact },
|
||||||
|
{ "togglebar", togglebar },
|
||||||
|
{ "incnmaster", incnmaster },
|
||||||
|
{ "togglefloating", togglefloating },
|
||||||
|
{ "focusmon", focusmon },
|
||||||
|
{ "tagmon", tagmon },
|
||||||
|
{ "zoom", zoom },
|
||||||
|
{ "view", view },
|
||||||
|
{ "viewall", viewall },
|
||||||
|
{ "viewex", viewex },
|
||||||
|
{ "toggleview", view },
|
||||||
|
{ "toggleviewex", toggleviewex },
|
||||||
|
{ "tag", tag },
|
||||||
|
{ "tagall", tagall },
|
||||||
|
{ "tagex", tagex },
|
||||||
|
{ "toggletag", tag },
|
||||||
|
{ "toggletagex", toggletagex },
|
||||||
|
{ "killclient", killclient },
|
||||||
|
{ "quit", quit },
|
||||||
|
{ "setlayout", setlayout },
|
||||||
|
{ "setlayoutex", setlayoutex },
|
||||||
|
};
|
||||||
|
164
config.h
164
config.h
@ -1,164 +0,0 @@
|
|||||||
/* See LICENSE file for copyright and license details. */
|
|
||||||
|
|
||||||
/* includes */
|
|
||||||
#include <X11/XF86keysym.h>
|
|
||||||
#include "movestack.c"
|
|
||||||
|
|
||||||
/* appearance */
|
|
||||||
static const unsigned int borderpx = 3; /* border pixel of windows */
|
|
||||||
static const int gappx = 15; /* gaps between windows */
|
|
||||||
static const unsigned int snap = 10; /* snap pixel */
|
|
||||||
static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */
|
|
||||||
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[] = { "NotoSans Nerd Font:size=10" };
|
|
||||||
static const char col_gray1[] = "#282a36"; /* background color */
|
|
||||||
static const char col_gray2[] = "#44475a"; /* inactive window border color */
|
|
||||||
static const char col_gray3[] = "#f8f8f2"; /* font color */
|
|
||||||
static const char col_gray4[] = "#282a36"; /* current tag and current window font color */
|
|
||||||
static const char col_cyan[] = "#bd93f9"; /* Top bar second color and active window border color */
|
|
||||||
static const char *colors[][3] = {
|
|
||||||
/* fg bg border */
|
|
||||||
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
|
|
||||||
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
|
|
||||||
};
|
|
||||||
|
|
||||||
/* tagging */
|
|
||||||
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 */
|
|
||||||
{ "origin", NULL, NULL, 0, 1, -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 */
|
|
||||||
|
|
||||||
#include "layouts.c"
|
|
||||||
static const Layout layouts[] = {
|
|
||||||
/* symbol arrange function */
|
|
||||||
{ "[]=", tile }, /* first entry is default */
|
|
||||||
{ "><>", NULL }, /* no layout function means floating behavior */
|
|
||||||
{ "[M]", monocle },
|
|
||||||
{ "|M|", centeredmaster },
|
|
||||||
{ ">M>", centeredfloatingmaster },
|
|
||||||
{ "HHH", grid },
|
|
||||||
{ NULL, NULL },
|
|
||||||
};
|
|
||||||
|
|
||||||
/* key definitions */
|
|
||||||
#define MODKEY Mod4Mask /* Mod1Mask = Alt, Mod4Mask = Super */
|
|
||||||
#define TAGKEYS(KEY,TAG) \
|
|
||||||
{ MODKEY, KEY, comboview, {.ui = 1 << TAG} }, \
|
|
||||||
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
|
|
||||||
{ MODKEY|ShiftMask, KEY, combotag, {.ui = 1 << TAG} }, \
|
|
||||||
{ 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 } }
|
|
||||||
|
|
||||||
/* configuration parameters */
|
|
||||||
static const char rootdir[] = "/home/sravan/.config"; /* Location of dwm source code */
|
|
||||||
|
|
||||||
/* commands */
|
|
||||||
static const char *rofiruncmd[] = { "rofi", "-show", "drun", NULL };
|
|
||||||
static const char *roficlipcmd[] = { "rofi", "-show", "clipboard", NULL };
|
|
||||||
static const char *lockcmd[] = { "light-locker-command", "--lock", NULL };
|
|
||||||
static const char *sleepcmd[] = { "systemctl", "suspend", NULL };
|
|
||||||
static const char *termcmd[] = { "alacritty", NULL };
|
|
||||||
static const char *upvolcmd[] = { "/usr/bin/pactl", "set-sink-volume", "@DEFAULT_SINK@", "+1%", NULL };
|
|
||||||
static const char *downvolcmd[] = { "/usr/bin/pactl", "set-sink-volume", "@DEFAULT_SINK@", "-1%", NULL };
|
|
||||||
static const char *mutevolcmd[] = { "/usr/bin/pactl", "set-sink-mute", "@DEFAULT_SINK@", "toggle", NULL };
|
|
||||||
static const char *brightness_up[] = { "xbacklight", "-inc", "1", NULL };
|
|
||||||
static const char *brightness_down[] = { "xbacklight", "-dec", "1", NULL };
|
|
||||||
static const char *playerplaypausecmd[] = { "playerctl", "--player=playerctld", "play-pause", NULL };
|
|
||||||
static const char *playernextcmd[] = { "playerctl", "--player=playerctld", "next", NULL };
|
|
||||||
static const char *playerprevcmd[] = { "playerctl", "--player=playerctld", "previous", NULL };
|
|
||||||
static const char *flameshotcmd[] = { "flameshot", "gui", NULL };
|
|
||||||
|
|
||||||
/* key definitions */
|
|
||||||
static Key keys[] = {
|
|
||||||
/* modifier key function argument */
|
|
||||||
{ MODKEY, XK_p, spawn, {.v = rofiruncmd} },
|
|
||||||
{ MODKEY, XK_c, spawn, {.v = roficlipcmd} },
|
|
||||||
{ MODKEY|ShiftMask, XK_l, spawn, {.v = lockcmd} },
|
|
||||||
{ MODKEY|ShiftMask, XK_s, spawn, {.v = sleepcmd} },
|
|
||||||
{ 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|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} },
|
|
||||||
{ 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_g, setlayout, {.v = &layouts[5]} },
|
|
||||||
{ MODKEY|ControlMask, XK_comma, cyclelayout, {.i = -1 } },
|
|
||||||
{ MODKEY|ControlMask, XK_period, cyclelayout, {.i = +1 } },
|
|
||||||
{ MODKEY, XK_space, setlayout, {0} },
|
|
||||||
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
|
||||||
{ MODKEY, XK_0, view, {.ui = ~0} },
|
|
||||||
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0} },
|
|
||||||
{ MODKEY, XK_comma, focusmon, {.i = -1} },
|
|
||||||
{ MODKEY, XK_period, focusmon, {.i = +1} },
|
|
||||||
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1} },
|
|
||||||
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1} },
|
|
||||||
{ MODKEY, XK_minus, setgaps, {.i = -5 } },
|
|
||||||
{ MODKEY, XK_equal, setgaps, {.i = +5 } },
|
|
||||||
{ MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } },
|
|
||||||
{ 0, XF86XK_AudioLowerVolume, spawn, {.v = downvolcmd} },
|
|
||||||
{ 0, XF86XK_AudioMute, spawn, {.v = mutevolcmd} },
|
|
||||||
{ 0, XF86XK_AudioRaiseVolume, spawn, {.v = upvolcmd} },
|
|
||||||
{ 0, XF86XK_MonBrightnessUp, spawn, {.v = brightness_up} },
|
|
||||||
{ 0, XF86XK_MonBrightnessDown, spawn, {.v = brightness_down} },
|
|
||||||
{ 0, XF86XK_AudioPlay, spawn, {.v = playerplaypausecmd} },
|
|
||||||
{ 0, XF86XK_AudioNext, spawn, {.v = playernextcmd} },
|
|
||||||
{ 0, XF86XK_AudioPrev, spawn, {.v = playerprevcmd} },
|
|
||||||
{ 0, XK_Print, spawn, {.v = flameshotcmd} },
|
|
||||||
TAGKEYS( XK_1, 0)
|
|
||||||
TAGKEYS( XK_2, 1)
|
|
||||||
TAGKEYS( XK_3, 2)
|
|
||||||
TAGKEYS( XK_4, 3)
|
|
||||||
TAGKEYS( XK_5, 4)
|
|
||||||
TAGKEYS( XK_6, 5)
|
|
||||||
TAGKEYS( XK_7, 6)
|
|
||||||
TAGKEYS( XK_8, 7)
|
|
||||||
TAGKEYS( XK_9, 8)
|
|
||||||
{ MODKEY|ShiftMask, XK_q, quit, {0} },
|
|
||||||
{ MODKEY|ControlMask|ShiftMask, XK_q, quit, {1} },
|
|
||||||
};
|
|
||||||
|
|
||||||
/* button definitions */
|
|
||||||
/* 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]} },
|
|
||||||
{ 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} },
|
|
||||||
};
|
|
@ -19,10 +19,15 @@ FREETYPELIBS = -lfontconfig -lXft
|
|||||||
FREETYPEINC = /usr/include/freetype2
|
FREETYPEINC = /usr/include/freetype2
|
||||||
# OpenBSD (uncomment)
|
# OpenBSD (uncomment)
|
||||||
#FREETYPEINC = ${X11INC}/freetype2
|
#FREETYPEINC = ${X11INC}/freetype2
|
||||||
|
#KVMLIB = -lkvm
|
||||||
|
|
||||||
|
# yajl
|
||||||
|
YAJLLIBS = -lyajl
|
||||||
|
YAJLINC = /usr/include/yajl
|
||||||
|
|
||||||
# includes and libs
|
# includes and libs
|
||||||
INCS = -I${X11INC} -I${FREETYPEINC}
|
INCS = -I${X11INC} -I${FREETYPEINC} -I${YAJLINC}
|
||||||
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
|
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${YAJLLIBS} -lX11-xcb -lxcb -lxcb-res ${KVMLIB}
|
||||||
|
|
||||||
# flags
|
# flags
|
||||||
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
|
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
|
||||||
|
4
drw.c
4
drw.c
@ -203,12 +203,14 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
|
|||||||
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);
|
||||||
|
|
||||||
|
dest->pixel |= 0xff << 24;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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, char *clrnames[], size_t clrcount)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
Clr *ret;
|
Clr *ret;
|
||||||
|
2
drw.h
2
drw.h
@ -39,7 +39,7 @@ void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned in
|
|||||||
|
|
||||||
/* 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, 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);
|
||||||
|
548
dwm-msg.c
Normal file
548
dwm-msg.c
Normal file
@ -0,0 +1,548 @@
|
|||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <yajl/yajl_gen.h>
|
||||||
|
|
||||||
|
#define IPC_MAGIC "DWM-IPC"
|
||||||
|
// clang-format off
|
||||||
|
#define IPC_MAGIC_ARR { 'D', 'W', 'M', '-', 'I', 'P', 'C' }
|
||||||
|
// clang-format on
|
||||||
|
#define IPC_MAGIC_LEN 7 // Not including null char
|
||||||
|
|
||||||
|
#define IPC_EVENT_TAG_CHANGE "tag_change_event"
|
||||||
|
#define IPC_EVENT_CLIENT_FOCUS_CHANGE "client_focus_change_event"
|
||||||
|
#define IPC_EVENT_LAYOUT_CHANGE "layout_change_event"
|
||||||
|
#define IPC_EVENT_MONITOR_FOCUS_CHANGE "monitor_focus_change_event"
|
||||||
|
#define IPC_EVENT_FOCUSED_TITLE_CHANGE "focused_title_change_event"
|
||||||
|
#define IPC_EVENT_FOCUSED_STATE_CHANGE "focused_state_change_event"
|
||||||
|
|
||||||
|
#define YSTR(str) yajl_gen_string(gen, (unsigned char *)str, strlen(str))
|
||||||
|
#define YINT(num) yajl_gen_integer(gen, num)
|
||||||
|
#define YDOUBLE(num) yajl_gen_double(gen, num)
|
||||||
|
#define YBOOL(v) yajl_gen_bool(gen, v)
|
||||||
|
#define YNULL() yajl_gen_null(gen)
|
||||||
|
#define YARR(body) \
|
||||||
|
{ \
|
||||||
|
yajl_gen_array_open(gen); \
|
||||||
|
body; \
|
||||||
|
yajl_gen_array_close(gen); \
|
||||||
|
}
|
||||||
|
#define YMAP(body) \
|
||||||
|
{ \
|
||||||
|
yajl_gen_map_open(gen); \
|
||||||
|
body; \
|
||||||
|
yajl_gen_map_close(gen); \
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef unsigned long Window;
|
||||||
|
|
||||||
|
const char *DEFAULT_SOCKET_PATH = "/tmp/dwm.sock";
|
||||||
|
static int sock_fd = -1;
|
||||||
|
static unsigned int ignore_reply = 0;
|
||||||
|
|
||||||
|
typedef enum IPCMessageType {
|
||||||
|
IPC_TYPE_RUN_COMMAND = 0,
|
||||||
|
IPC_TYPE_GET_MONITORS = 1,
|
||||||
|
IPC_TYPE_GET_TAGS = 2,
|
||||||
|
IPC_TYPE_GET_LAYOUTS = 3,
|
||||||
|
IPC_TYPE_GET_DWM_CLIENT = 4,
|
||||||
|
IPC_TYPE_SUBSCRIBE = 5,
|
||||||
|
IPC_TYPE_EVENT = 6
|
||||||
|
} IPCMessageType;
|
||||||
|
|
||||||
|
// Every IPC message must begin with this
|
||||||
|
typedef struct dwm_ipc_header {
|
||||||
|
uint8_t magic[IPC_MAGIC_LEN];
|
||||||
|
uint32_t size;
|
||||||
|
uint8_t type;
|
||||||
|
} __attribute((packed)) dwm_ipc_header_t;
|
||||||
|
|
||||||
|
static int
|
||||||
|
recv_message(uint8_t *msg_type, uint32_t *reply_size, uint8_t **reply)
|
||||||
|
{
|
||||||
|
uint32_t read_bytes = 0;
|
||||||
|
const int32_t to_read = sizeof(dwm_ipc_header_t);
|
||||||
|
char header[to_read];
|
||||||
|
char *walk = header;
|
||||||
|
|
||||||
|
// Try to read header
|
||||||
|
while (read_bytes < to_read) {
|
||||||
|
ssize_t n = read(sock_fd, header + read_bytes, to_read - read_bytes);
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
if (read_bytes == 0) {
|
||||||
|
fprintf(stderr, "Unexpectedly reached EOF while reading header.");
|
||||||
|
fprintf(stderr,
|
||||||
|
"Read %" PRIu32 " bytes, expected %" PRIu32 " total bytes.\n",
|
||||||
|
read_bytes, to_read);
|
||||||
|
return -2;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Unexpectedly reached EOF while reading header.");
|
||||||
|
fprintf(stderr,
|
||||||
|
"Read %" PRIu32 " bytes, expected %" PRIu32 " total bytes.\n",
|
||||||
|
read_bytes, to_read);
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
} else if (n == -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
read_bytes += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if magic string in header matches
|
||||||
|
if (memcmp(walk, IPC_MAGIC, IPC_MAGIC_LEN) != 0) {
|
||||||
|
fprintf(stderr, "Invalid magic string. Got '%.*s', expected '%s'\n",
|
||||||
|
IPC_MAGIC_LEN, walk, IPC_MAGIC);
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
walk += IPC_MAGIC_LEN;
|
||||||
|
|
||||||
|
// Extract reply size
|
||||||
|
memcpy(reply_size, walk, sizeof(uint32_t));
|
||||||
|
walk += sizeof(uint32_t);
|
||||||
|
|
||||||
|
// Extract message type
|
||||||
|
memcpy(msg_type, walk, sizeof(uint8_t));
|
||||||
|
walk += sizeof(uint8_t);
|
||||||
|
|
||||||
|
(*reply) = malloc(*reply_size);
|
||||||
|
|
||||||
|
// Extract payload
|
||||||
|
read_bytes = 0;
|
||||||
|
while (read_bytes < *reply_size) {
|
||||||
|
ssize_t n = read(sock_fd, *reply + read_bytes, *reply_size - read_bytes);
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
fprintf(stderr, "Unexpectedly reached EOF while reading payload.");
|
||||||
|
fprintf(stderr, "Read %" PRIu32 " bytes, expected %" PRIu32 " bytes.\n",
|
||||||
|
read_bytes, *reply_size);
|
||||||
|
free(*reply);
|
||||||
|
return -2;
|
||||||
|
} else if (n == -1) {
|
||||||
|
if (errno == EINTR || errno == EAGAIN) continue;
|
||||||
|
free(*reply);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
read_bytes += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
read_socket(IPCMessageType *msg_type, uint32_t *msg_size, char **msg)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
while (ret != 0) {
|
||||||
|
ret = recv_message((uint8_t *)msg_type, msg_size, (uint8_t **)msg);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
// Try again (non-fatal error)
|
||||||
|
if (ret == -1 && (errno == EINTR || errno == EAGAIN)) continue;
|
||||||
|
|
||||||
|
fprintf(stderr, "Error receiving response from socket. ");
|
||||||
|
fprintf(stderr, "The connection might have been lost.\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
write_socket(const void *buf, size_t count)
|
||||||
|
{
|
||||||
|
size_t written = 0;
|
||||||
|
|
||||||
|
while (written < count) {
|
||||||
|
const ssize_t n =
|
||||||
|
write(sock_fd, ((uint8_t *)buf) + written, count - written);
|
||||||
|
|
||||||
|
if (n == -1) {
|
||||||
|
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
written += n;
|
||||||
|
}
|
||||||
|
return written;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
connect_to_socket()
|
||||||
|
{
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
|
||||||
|
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
// Initialize struct to 0
|
||||||
|
memset(&addr, 0, sizeof(struct sockaddr_un));
|
||||||
|
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
strcpy(addr.sun_path, DEFAULT_SOCKET_PATH);
|
||||||
|
|
||||||
|
connect(sock, (const struct sockaddr *)&addr, sizeof(struct sockaddr_un));
|
||||||
|
|
||||||
|
sock_fd = sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
send_message(IPCMessageType msg_type, uint32_t msg_size, uint8_t *msg)
|
||||||
|
{
|
||||||
|
dwm_ipc_header_t header = {
|
||||||
|
.magic = IPC_MAGIC_ARR, .size = msg_size, .type = msg_type};
|
||||||
|
|
||||||
|
size_t header_size = sizeof(dwm_ipc_header_t);
|
||||||
|
size_t total_size = header_size + msg_size;
|
||||||
|
|
||||||
|
uint8_t buffer[total_size];
|
||||||
|
|
||||||
|
// Copy header to buffer
|
||||||
|
memcpy(buffer, &header, header_size);
|
||||||
|
// Copy message to buffer
|
||||||
|
memcpy(buffer + header_size, msg, header.size);
|
||||||
|
|
||||||
|
write_socket(buffer, total_size);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_float(const char *s)
|
||||||
|
{
|
||||||
|
size_t len = strlen(s);
|
||||||
|
int is_dot_used = 0;
|
||||||
|
int is_minus_used = 0;
|
||||||
|
|
||||||
|
// Floats can only have one decimal point in between or digits
|
||||||
|
// Optionally, floats can also be below zero (negative)
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
if (isdigit(s[i]))
|
||||||
|
continue;
|
||||||
|
else if (!is_dot_used && s[i] == '.' && i != 0 && i != len - 1) {
|
||||||
|
is_dot_used = 1;
|
||||||
|
continue;
|
||||||
|
} else if (!is_minus_used && s[i] == '-' && i == 0) {
|
||||||
|
is_minus_used = 1;
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_unsigned_int(const char *s)
|
||||||
|
{
|
||||||
|
size_t len = strlen(s);
|
||||||
|
|
||||||
|
// Unsigned int can only have digits
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
if (isdigit(s[i]))
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_signed_int(const char *s)
|
||||||
|
{
|
||||||
|
size_t len = strlen(s);
|
||||||
|
|
||||||
|
// Signed int can only have digits and a negative sign at the start
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
if (isdigit(s[i]))
|
||||||
|
continue;
|
||||||
|
else if (i == 0 && s[i] == '-') {
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
flush_socket_reply()
|
||||||
|
{
|
||||||
|
IPCMessageType reply_type;
|
||||||
|
uint32_t reply_size;
|
||||||
|
char *reply;
|
||||||
|
|
||||||
|
read_socket(&reply_type, &reply_size, &reply);
|
||||||
|
|
||||||
|
free(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_socket_reply()
|
||||||
|
{
|
||||||
|
IPCMessageType reply_type;
|
||||||
|
uint32_t reply_size;
|
||||||
|
char *reply;
|
||||||
|
|
||||||
|
read_socket(&reply_type, &reply_size, &reply);
|
||||||
|
|
||||||
|
printf("%.*s\n", reply_size, reply);
|
||||||
|
fflush(stdout);
|
||||||
|
free(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
run_command(const char *name, char *args[], int argc)
|
||||||
|
{
|
||||||
|
const unsigned char *msg;
|
||||||
|
size_t msg_size;
|
||||||
|
|
||||||
|
yajl_gen gen = yajl_gen_alloc(NULL);
|
||||||
|
|
||||||
|
// Message format:
|
||||||
|
// {
|
||||||
|
// "command": "<name>",
|
||||||
|
// "args": [ ... ]
|
||||||
|
// }
|
||||||
|
// clang-format off
|
||||||
|
YMAP(
|
||||||
|
YSTR("command"); YSTR(name);
|
||||||
|
YSTR("args"); YARR(
|
||||||
|
for (int i = 0; i < argc; i++) {
|
||||||
|
if (is_signed_int(args[i])) {
|
||||||
|
long long num = atoll(args[i]);
|
||||||
|
YINT(num);
|
||||||
|
} else if (is_float(args[i])) {
|
||||||
|
float num = atof(args[i]);
|
||||||
|
YDOUBLE(num);
|
||||||
|
} else {
|
||||||
|
YSTR(args[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
yajl_gen_get_buf(gen, &msg, &msg_size);
|
||||||
|
|
||||||
|
send_message(IPC_TYPE_RUN_COMMAND, msg_size, (uint8_t *)msg);
|
||||||
|
|
||||||
|
if (!ignore_reply)
|
||||||
|
print_socket_reply();
|
||||||
|
else
|
||||||
|
flush_socket_reply();
|
||||||
|
|
||||||
|
yajl_gen_free(gen);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_monitors()
|
||||||
|
{
|
||||||
|
send_message(IPC_TYPE_GET_MONITORS, 1, (uint8_t *)"");
|
||||||
|
print_socket_reply();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_tags()
|
||||||
|
{
|
||||||
|
send_message(IPC_TYPE_GET_TAGS, 1, (uint8_t *)"");
|
||||||
|
print_socket_reply();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_layouts()
|
||||||
|
{
|
||||||
|
send_message(IPC_TYPE_GET_LAYOUTS, 1, (uint8_t *)"");
|
||||||
|
print_socket_reply();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_dwm_client(Window win)
|
||||||
|
{
|
||||||
|
const unsigned char *msg;
|
||||||
|
size_t msg_size;
|
||||||
|
|
||||||
|
yajl_gen gen = yajl_gen_alloc(NULL);
|
||||||
|
|
||||||
|
// Message format:
|
||||||
|
// {
|
||||||
|
// "client_window_id": "<win>"
|
||||||
|
// }
|
||||||
|
// clang-format off
|
||||||
|
YMAP(
|
||||||
|
YSTR("client_window_id"); YINT(win);
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
yajl_gen_get_buf(gen, &msg, &msg_size);
|
||||||
|
|
||||||
|
send_message(IPC_TYPE_GET_DWM_CLIENT, msg_size, (uint8_t *)msg);
|
||||||
|
|
||||||
|
print_socket_reply();
|
||||||
|
|
||||||
|
yajl_gen_free(gen);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
subscribe(const char *event)
|
||||||
|
{
|
||||||
|
const unsigned char *msg;
|
||||||
|
size_t msg_size;
|
||||||
|
|
||||||
|
yajl_gen gen = yajl_gen_alloc(NULL);
|
||||||
|
|
||||||
|
// Message format:
|
||||||
|
// {
|
||||||
|
// "event": "<event>",
|
||||||
|
// "action": "subscribe"
|
||||||
|
// }
|
||||||
|
// clang-format off
|
||||||
|
YMAP(
|
||||||
|
YSTR("event"); YSTR(event);
|
||||||
|
YSTR("action"); YSTR("subscribe");
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
yajl_gen_get_buf(gen, &msg, &msg_size);
|
||||||
|
|
||||||
|
send_message(IPC_TYPE_SUBSCRIBE, msg_size, (uint8_t *)msg);
|
||||||
|
|
||||||
|
if (!ignore_reply)
|
||||||
|
print_socket_reply();
|
||||||
|
else
|
||||||
|
flush_socket_reply();
|
||||||
|
|
||||||
|
yajl_gen_free(gen);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
usage_error(const char *prog_name, const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
|
||||||
|
fprintf(stderr, "Error: ");
|
||||||
|
vfprintf(stderr, format, args);
|
||||||
|
fprintf(stderr, "\nusage: %s <command> [...]\n", prog_name);
|
||||||
|
fprintf(stderr, "Try '%s help'\n", prog_name);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_usage(const char *name)
|
||||||
|
{
|
||||||
|
printf("usage: %s [options] <command> [...]\n", name);
|
||||||
|
puts("");
|
||||||
|
puts("Commands:");
|
||||||
|
puts(" run_command <name> [args...] Run an IPC command");
|
||||||
|
puts("");
|
||||||
|
puts(" get_monitors Get monitor properties");
|
||||||
|
puts("");
|
||||||
|
puts(" get_tags Get list of tags");
|
||||||
|
puts("");
|
||||||
|
puts(" get_layouts Get list of layouts");
|
||||||
|
puts("");
|
||||||
|
puts(" get_dwm_client <window_id> Get dwm client proprties");
|
||||||
|
puts("");
|
||||||
|
puts(" subscribe [events...] Subscribe to specified events");
|
||||||
|
puts(" Options: " IPC_EVENT_TAG_CHANGE ",");
|
||||||
|
puts(" " IPC_EVENT_LAYOUT_CHANGE ",");
|
||||||
|
puts(" " IPC_EVENT_CLIENT_FOCUS_CHANGE ",");
|
||||||
|
puts(" " IPC_EVENT_MONITOR_FOCUS_CHANGE ",");
|
||||||
|
puts(" " IPC_EVENT_FOCUSED_TITLE_CHANGE ",");
|
||||||
|
puts(" " IPC_EVENT_FOCUSED_STATE_CHANGE);
|
||||||
|
puts("");
|
||||||
|
puts(" help Display this message");
|
||||||
|
puts("");
|
||||||
|
puts("Options:");
|
||||||
|
puts(" --ignore-reply Don't print reply messages from");
|
||||||
|
puts(" run_command and subscribe.");
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
const char *prog_name = argv[0];
|
||||||
|
|
||||||
|
connect_to_socket();
|
||||||
|
if (sock_fd == -1) {
|
||||||
|
fprintf(stderr, "Failed to connect to socket\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 1;
|
||||||
|
if (i < argc && strcmp(argv[i], "--ignore-reply") == 0) {
|
||||||
|
ignore_reply = 1;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i >= argc) usage_error(prog_name, "Expected an argument, got none");
|
||||||
|
|
||||||
|
if (strcmp(argv[i], "help") == 0)
|
||||||
|
print_usage(prog_name);
|
||||||
|
else if (strcmp(argv[i], "run_command") == 0) {
|
||||||
|
if (++i >= argc) usage_error(prog_name, "No command specified");
|
||||||
|
// Command name
|
||||||
|
char *command = argv[i];
|
||||||
|
// Command arguments are everything after command name
|
||||||
|
char **command_args = argv + ++i;
|
||||||
|
// Number of command arguments
|
||||||
|
int command_argc = argc - i;
|
||||||
|
run_command(command, command_args, command_argc);
|
||||||
|
} else if (strcmp(argv[i], "get_monitors") == 0) {
|
||||||
|
get_monitors();
|
||||||
|
} else if (strcmp(argv[i], "get_tags") == 0) {
|
||||||
|
get_tags();
|
||||||
|
} else if (strcmp(argv[i], "get_layouts") == 0) {
|
||||||
|
get_layouts();
|
||||||
|
} else if (strcmp(argv[i], "get_dwm_client") == 0) {
|
||||||
|
if (++i < argc) {
|
||||||
|
if (is_unsigned_int(argv[i])) {
|
||||||
|
Window win = atol(argv[i]);
|
||||||
|
get_dwm_client(win);
|
||||||
|
} else
|
||||||
|
usage_error(prog_name, "Expected unsigned integer argument");
|
||||||
|
} else
|
||||||
|
usage_error(prog_name, "Expected the window id");
|
||||||
|
} else if (strcmp(argv[i], "subscribe") == 0) {
|
||||||
|
if (++i < argc) {
|
||||||
|
for (int j = i; j < argc; j++) subscribe(argv[j]);
|
||||||
|
} else
|
||||||
|
usage_error(prog_name, "Expected event name");
|
||||||
|
// Keep listening for events forever
|
||||||
|
while (1) {
|
||||||
|
print_socket_reply();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
usage_error(prog_name, "Invalid argument '%s'", argv[i]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
91
dwm.1
91
dwm.1
@ -29,15 +29,10 @@ color. The tags of the focused window are indicated with a filled square in the
|
|||||||
top left corner. The tags which are applied to one or more windows are
|
top left corner. The tags which are applied to one or more windows are
|
||||||
indicated with an empty square in the top left corner.
|
indicated with an empty square in the top left corner.
|
||||||
.P
|
.P
|
||||||
|
The attach below patch makes newly spawned windows attach after the currently
|
||||||
|
selected window
|
||||||
|
.P
|
||||||
dwm draws a small border around windows to indicate the focus state.
|
dwm draws a small border around windows to indicate the focus state.
|
||||||
.P
|
|
||||||
On start, dwm can start additional programs that may be specified in two special
|
|
||||||
shell scripts (see the FILES section below), autostart_blocking.sh and
|
|
||||||
autostart.sh. The former is executed first and dwm will wait for its
|
|
||||||
termination before starting. The latter is executed in the background before
|
|
||||||
dwm enters its handler loop.
|
|
||||||
.P
|
|
||||||
Either of these files may be omitted.
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
.B \-v
|
.B \-v
|
||||||
@ -70,24 +65,9 @@ Start
|
|||||||
.TP
|
.TP
|
||||||
.B Mod1\-p
|
.B Mod1\-p
|
||||||
Spawn
|
Spawn
|
||||||
.BR rofi(1)
|
.BR dmenu(1)
|
||||||
for launching other programs.
|
for launching other programs.
|
||||||
.TP
|
.TP
|
||||||
.B Mod1\-c
|
|
||||||
Spawn
|
|
||||||
.BR rofi(1)
|
|
||||||
for Greenclip clipboard manager
|
|
||||||
.TP
|
|
||||||
.B Mod1\-Shift\-n
|
|
||||||
Spawn
|
|
||||||
.BR light-locker(1)
|
|
||||||
to lock screen.
|
|
||||||
.TP
|
|
||||||
.B Mod1\-Shift\-s
|
|
||||||
Spawn
|
|
||||||
.BR suspend(1)
|
|
||||||
to lock screen and go to sleep.
|
|
||||||
.TP
|
|
||||||
.B Mod1\-,
|
.B Mod1\-,
|
||||||
Focus previous screen, if any.
|
Focus previous screen, if any.
|
||||||
.TP
|
.TP
|
||||||
@ -100,15 +80,6 @@ Send focused window to previous screen, if any.
|
|||||||
.B Mod1\-Shift\-.
|
.B Mod1\-Shift\-.
|
||||||
Send focused window to next screen, if any.
|
Send focused window to next screen, if any.
|
||||||
.TP
|
.TP
|
||||||
.B Mod1\--
|
|
||||||
Decrease window gap.
|
|
||||||
.TP
|
|
||||||
.B Mod1\-=
|
|
||||||
Increase window gap.
|
|
||||||
.TP
|
|
||||||
.B Mod1\-Shift\-=
|
|
||||||
Reset window gap to 0.
|
|
||||||
.TP
|
|
||||||
.B Mod1\-b
|
.B Mod1\-b
|
||||||
Toggles bar on and off.
|
Toggles bar on and off.
|
||||||
.TP
|
.TP
|
||||||
@ -121,15 +92,6 @@ Sets floating layout.
|
|||||||
.B Mod1\-m
|
.B Mod1\-m
|
||||||
Sets monocle layout.
|
Sets monocle layout.
|
||||||
.TP
|
.TP
|
||||||
.B Mod1\-u
|
|
||||||
Sets centered master layout.
|
|
||||||
.TP
|
|
||||||
.B Mod1\-o
|
|
||||||
Sets centered floating master layout.
|
|
||||||
.TP
|
|
||||||
.B Mod1\-g
|
|
||||||
Sets grid layout.
|
|
||||||
.TP
|
|
||||||
.B Mod1\-space
|
.B Mod1\-space
|
||||||
Toggles between current and previous layout.
|
Toggles between current and previous layout.
|
||||||
.TP
|
.TP
|
||||||
@ -157,6 +119,15 @@ Increase master area size.
|
|||||||
.B Mod1\-h
|
.B Mod1\-h
|
||||||
Decrease master area size.
|
Decrease master area size.
|
||||||
.TP
|
.TP
|
||||||
|
.B Mod1\-Shift\-l
|
||||||
|
Increase client weight (cfacts patch).
|
||||||
|
.TP
|
||||||
|
.B Mod1\-Shift\-h
|
||||||
|
Decrease client weight (cfacts patch).
|
||||||
|
.TP
|
||||||
|
.B Mod1\-Shift\-o
|
||||||
|
Reset client weight (cfacts patch).
|
||||||
|
.TP
|
||||||
.B Mod1\-Return
|
.B Mod1\-Return
|
||||||
Zooms/cycles focused window to/from master area (tiled layouts only).
|
Zooms/cycles focused window to/from master area (tiled layouts only).
|
||||||
.TP
|
.TP
|
||||||
@ -166,9 +137,21 @@ Close focused window.
|
|||||||
.B Mod1\-Shift\-space
|
.B Mod1\-Shift\-space
|
||||||
Toggle focused window between tiled and floating state.
|
Toggle focused window between tiled and floating state.
|
||||||
.TP
|
.TP
|
||||||
|
.B Mod1\-Control\-f
|
||||||
|
Toggle fullscreen (actualfullscreen patch).
|
||||||
|
.TP
|
||||||
|
.B Mod1\-Control\-tab
|
||||||
|
Toggle attach below (attachbelow patch).
|
||||||
|
.TP
|
||||||
.B Mod1\-Tab
|
.B Mod1\-Tab
|
||||||
Toggles to the previously selected tags.
|
Toggles to the previously selected tags.
|
||||||
.TP
|
.TP
|
||||||
|
.B Mod1\-Shift\-j
|
||||||
|
Increase window size while maintaining aspect ratio (aspectresize patch).
|
||||||
|
.TP
|
||||||
|
.B Mod1\-Shift\-k
|
||||||
|
Decrease window size while maintaining aspect ratio (aspectresize patch).
|
||||||
|
.TP
|
||||||
.B Mod1\-Shift\-[1..n]
|
.B Mod1\-Shift\-[1..n]
|
||||||
Apply nth tag to focused window.
|
Apply nth tag to focused window.
|
||||||
.TP
|
.TP
|
||||||
@ -189,9 +172,6 @@ Add/remove all windows with nth tag to/from the view.
|
|||||||
.TP
|
.TP
|
||||||
.B Mod1\-Shift\-q
|
.B Mod1\-Shift\-q
|
||||||
Quit dwm.
|
Quit dwm.
|
||||||
.TP
|
|
||||||
.B Mod1\-Control\-Shift\-q
|
|
||||||
Restart dwm.
|
|
||||||
.SS Mouse commands
|
.SS Mouse commands
|
||||||
.TP
|
.TP
|
||||||
.B Mod1\-Button1
|
.B Mod1\-Button1
|
||||||
@ -202,30 +182,11 @@ Toggles focused window between floating and tiled state.
|
|||||||
.TP
|
.TP
|
||||||
.B Mod1\-Button3
|
.B Mod1\-Button3
|
||||||
Resize focused window while dragging. Tiled windows will be toggled to the floating state.
|
Resize focused window while dragging. Tiled windows will be toggled to the floating state.
|
||||||
.SH FILES
|
|
||||||
The files containing programs to be started along with dwm are searched for in
|
|
||||||
the dwm root directory.
|
|
||||||
.P
|
|
||||||
The first existing directory is scanned for any of the autostart files below.
|
|
||||||
.TP 15
|
|
||||||
autostart.sh
|
|
||||||
This file is started as a shell background process before dwm enters its handler
|
|
||||||
loop.
|
|
||||||
.TP 15
|
|
||||||
autostart_blocking.sh
|
|
||||||
This file is started before any autostart.sh; dwm waits for its termination.
|
|
||||||
.SH CUSTOMIZATION
|
.SH CUSTOMIZATION
|
||||||
dwm is customized by creating a custom config.h and (re)compiling the source
|
dwm is customized by creating a custom config.h and (re)compiling the source
|
||||||
code. This keeps it fast, secure and simple.
|
code. This keeps it fast, secure and simple.
|
||||||
.SH SIGNALS
|
|
||||||
.TP
|
|
||||||
.B SIGHUP - 1
|
|
||||||
Restart the dwm process.
|
|
||||||
.TP
|
|
||||||
.B SIGTERM - 15
|
|
||||||
Cleanly terminate the dwm process.
|
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR rofi (1),
|
.BR dmenu (1),
|
||||||
.BR st (1)
|
.BR st (1)
|
||||||
.SH ISSUES
|
.SH ISSUES
|
||||||
Java applications which use the XToolkit/XAWT backend may draw grey windows
|
Java applications which use the XToolkit/XAWT backend may draw grey windows
|
||||||
|
40
dwmc
Executable file
40
dwmc
Executable file
@ -0,0 +1,40 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
signal() {
|
||||||
|
xsetroot -name "fsignal:$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
case $# in
|
||||||
|
1)
|
||||||
|
case $1 in
|
||||||
|
setlayout | view | viewall | togglebar | togglefloating | zoom | killclient | quit)
|
||||||
|
signal $1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown command or missing one argument."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
case $1 in
|
||||||
|
view)
|
||||||
|
signal $1 ui $2
|
||||||
|
;;
|
||||||
|
viewex | toggleviewex | tagex | toggletagex | setlayoutex | focusstack | incnmaster | focusmon | tagmon)
|
||||||
|
signal $1 i $2
|
||||||
|
;;
|
||||||
|
setmfact)
|
||||||
|
signal $1 f $2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown command or one too many arguments."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Too many arguments."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
320
ipc.h
Normal file
320
ipc.h
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
#ifndef IPC_H_
|
||||||
|
#define IPC_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/epoll.h>
|
||||||
|
#include <yajl/yajl_gen.h>
|
||||||
|
|
||||||
|
#include "IPCClient.h"
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
#define IPC_MAGIC "DWM-IPC"
|
||||||
|
#define IPC_MAGIC_ARR { 'D', 'W', 'M', '-', 'I', 'P', 'C'}
|
||||||
|
#define IPC_MAGIC_LEN 7 // Not including null char
|
||||||
|
|
||||||
|
#define IPCCOMMAND(FUNC, ARGC, TYPES) \
|
||||||
|
{ #FUNC, {FUNC }, ARGC, (ArgType[ARGC])TYPES }
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
typedef enum IPCMessageType {
|
||||||
|
IPC_TYPE_RUN_COMMAND = 0,
|
||||||
|
IPC_TYPE_GET_MONITORS = 1,
|
||||||
|
IPC_TYPE_GET_TAGS = 2,
|
||||||
|
IPC_TYPE_GET_LAYOUTS = 3,
|
||||||
|
IPC_TYPE_GET_DWM_CLIENT = 4,
|
||||||
|
IPC_TYPE_SUBSCRIBE = 5,
|
||||||
|
IPC_TYPE_EVENT = 6
|
||||||
|
} IPCMessageType;
|
||||||
|
|
||||||
|
typedef enum IPCEvent {
|
||||||
|
IPC_EVENT_TAG_CHANGE = 1 << 0,
|
||||||
|
IPC_EVENT_CLIENT_FOCUS_CHANGE = 1 << 1,
|
||||||
|
IPC_EVENT_LAYOUT_CHANGE = 1 << 2,
|
||||||
|
IPC_EVENT_MONITOR_FOCUS_CHANGE = 1 << 3,
|
||||||
|
IPC_EVENT_FOCUSED_TITLE_CHANGE = 1 << 4,
|
||||||
|
IPC_EVENT_FOCUSED_STATE_CHANGE = 1 << 5
|
||||||
|
} IPCEvent;
|
||||||
|
|
||||||
|
typedef enum IPCSubscriptionAction {
|
||||||
|
IPC_ACTION_UNSUBSCRIBE = 0,
|
||||||
|
IPC_ACTION_SUBSCRIBE = 1
|
||||||
|
} IPCSubscriptionAction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Every IPC packet starts with this structure
|
||||||
|
*/
|
||||||
|
typedef struct dwm_ipc_header {
|
||||||
|
uint8_t magic[IPC_MAGIC_LEN];
|
||||||
|
uint32_t size;
|
||||||
|
uint8_t type;
|
||||||
|
} __attribute((packed)) dwm_ipc_header_t;
|
||||||
|
|
||||||
|
typedef enum ArgType {
|
||||||
|
ARG_TYPE_NONE = 0,
|
||||||
|
ARG_TYPE_UINT = 1,
|
||||||
|
ARG_TYPE_SINT = 2,
|
||||||
|
ARG_TYPE_FLOAT = 3,
|
||||||
|
ARG_TYPE_PTR = 4,
|
||||||
|
ARG_TYPE_STR = 5
|
||||||
|
} ArgType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An IPCCommand function can have either of these function signatures
|
||||||
|
*/
|
||||||
|
typedef union ArgFunction {
|
||||||
|
void (*single_param)(const Arg *);
|
||||||
|
void (*array_param)(const Arg *, int);
|
||||||
|
} ArgFunction;
|
||||||
|
|
||||||
|
typedef struct IPCCommand {
|
||||||
|
char *name;
|
||||||
|
ArgFunction func;
|
||||||
|
unsigned int argc;
|
||||||
|
ArgType *arg_types;
|
||||||
|
} IPCCommand;
|
||||||
|
|
||||||
|
typedef struct IPCParsedCommand {
|
||||||
|
char *name;
|
||||||
|
Arg *args;
|
||||||
|
ArgType *arg_types;
|
||||||
|
unsigned int argc;
|
||||||
|
} IPCParsedCommand;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the IPC socket and the IPC module
|
||||||
|
*
|
||||||
|
* @param socket_path Path to create the socket at
|
||||||
|
* @param epoll_fd File descriptor for epoll
|
||||||
|
* @param commands Address of IPCCommands array defined in config.h
|
||||||
|
* @param commands_len Length of commands[] array
|
||||||
|
*
|
||||||
|
* @return int The file descriptor of the socket if it was successfully created,
|
||||||
|
* -1 otherwise
|
||||||
|
*/
|
||||||
|
int ipc_init(const char *socket_path, const int p_epoll_fd,
|
||||||
|
IPCCommand commands[], const int commands_len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uninitialize the socket and module. Free allocated memory and restore static
|
||||||
|
* variables to their state before ipc_init
|
||||||
|
*/
|
||||||
|
void ipc_cleanup();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the file descriptor of the IPC socket
|
||||||
|
*
|
||||||
|
* @return int File descriptor of IPC socket, -1 if socket not created.
|
||||||
|
*/
|
||||||
|
int ipc_get_sock_fd();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get address to IPCClient with specified file descriptor
|
||||||
|
*
|
||||||
|
* @param fd File descriptor of IPC Client
|
||||||
|
*
|
||||||
|
* @return Address to IPCClient with specified file descriptor, -1 otherwise
|
||||||
|
*/
|
||||||
|
IPCClient *ipc_get_client(int fd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an IPC client exists with the specified file descriptor
|
||||||
|
*
|
||||||
|
* @param fd File descriptor
|
||||||
|
*
|
||||||
|
* @return int 1 if client exists, 0 otherwise
|
||||||
|
*/
|
||||||
|
int ipc_is_client_registered(int fd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disconnect an IPCClient from the socket and remove the client from the list
|
||||||
|
* of known connected clients
|
||||||
|
*
|
||||||
|
* @param c Address of IPCClient
|
||||||
|
*
|
||||||
|
* @return 0 if the client's file descriptor was closed successfully, the
|
||||||
|
* result of executing close() on the file descriptor otherwise.
|
||||||
|
*/
|
||||||
|
int ipc_drop_client(IPCClient *c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accept an IPC Client requesting to connect to the socket and add it to the
|
||||||
|
* list of clients
|
||||||
|
*
|
||||||
|
* @return File descriptor of new client, -1 on error
|
||||||
|
*/
|
||||||
|
int ipc_accept_client();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read an incoming message from an accepted IPC client
|
||||||
|
*
|
||||||
|
* @param c Address of IPCClient
|
||||||
|
* @param msg_type Address to IPCMessageType variable which will be assigned
|
||||||
|
* the message type of the received message
|
||||||
|
* @param msg_size Address to uint32_t variable which will be assigned the size
|
||||||
|
* of the received message
|
||||||
|
* @param msg Address to char* variable which will be assigned the address of
|
||||||
|
* the received message. This must be freed using free().
|
||||||
|
*
|
||||||
|
* @return 0 on success, -1 on error reading message, -2 if reading the message
|
||||||
|
* resulted in EAGAIN, EINTR, or EWOULDBLOCK.
|
||||||
|
*/
|
||||||
|
int ipc_read_client(IPCClient *c, IPCMessageType *msg_type, uint32_t *msg_size,
|
||||||
|
char **msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write any pending buffer of the client to the client's socket
|
||||||
|
*
|
||||||
|
* @param c Client whose buffer to write
|
||||||
|
*
|
||||||
|
* @return Number of bytes written >= 0, -1 otherwise. errno will still be set
|
||||||
|
* from the write operation.
|
||||||
|
*/
|
||||||
|
ssize_t ipc_write_client(IPCClient *c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a message in the specified client's buffer.
|
||||||
|
*
|
||||||
|
* @param c Client to prepare message for
|
||||||
|
* @param msg_type Type of message to prepare
|
||||||
|
* @param msg_size Size of the message in bytes. Should not exceed
|
||||||
|
* MAX_MESSAGE_SIZE
|
||||||
|
* @param msg Message to prepare (not including header). This pointer can be
|
||||||
|
* freed after the function invocation.
|
||||||
|
*/
|
||||||
|
void ipc_prepare_send_message(IPCClient *c, const IPCMessageType msg_type,
|
||||||
|
const uint32_t msg_size, const char *msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare an error message in the specified client's buffer
|
||||||
|
*
|
||||||
|
* @param c Client to prepare message for
|
||||||
|
* @param msg_type Type of message
|
||||||
|
* @param format Format string following vsprintf
|
||||||
|
* @param ... Arguments for format string
|
||||||
|
*/
|
||||||
|
void ipc_prepare_reply_failure(IPCClient *c, IPCMessageType msg_type,
|
||||||
|
const char *format, ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare a success message in the specified client's buffer
|
||||||
|
*
|
||||||
|
* @param c Client to prepare message for
|
||||||
|
* @param msg_type Type of message
|
||||||
|
*/
|
||||||
|
void ipc_prepare_reply_success(IPCClient *c, IPCMessageType msg_type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a tag_change_event to all subscribers. Should be called only when there
|
||||||
|
* has been a tag state change.
|
||||||
|
*
|
||||||
|
* @param mon_num The index of the monitor (Monitor.num property)
|
||||||
|
* @param old_state The old tag state
|
||||||
|
* @param new_state The new (now current) tag state
|
||||||
|
*/
|
||||||
|
void ipc_tag_change_event(const int mon_num, TagState old_state,
|
||||||
|
TagState new_state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a client_focus_change_event to all subscribers. Should be called only
|
||||||
|
* when the client focus changes.
|
||||||
|
*
|
||||||
|
* @param mon_num The index of the monitor (Monitor.num property)
|
||||||
|
* @param old_client The old DWM client selection (Monitor.oldsel)
|
||||||
|
* @param new_client The new (now current) DWM client selection
|
||||||
|
*/
|
||||||
|
void ipc_client_focus_change_event(const int mon_num, Client *old_client,
|
||||||
|
Client *new_client);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a layout_change_event to all subscribers. Should be called only
|
||||||
|
* when there has been a layout change.
|
||||||
|
*
|
||||||
|
* @param mon_num The index of the monitor (Monitor.num property)
|
||||||
|
* @param old_symbol The old layout symbol
|
||||||
|
* @param old_layout Address to the old Layout
|
||||||
|
* @param new_symbol The new (now current) layout symbol
|
||||||
|
* @param new_layout Address to the new Layout
|
||||||
|
*/
|
||||||
|
void ipc_layout_change_event(const int mon_num, const char *old_symbol,
|
||||||
|
const Layout *old_layout, const char *new_symbol,
|
||||||
|
const Layout *new_layout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a monitor_focus_change_event to all subscribers. Should be called only
|
||||||
|
* when the monitor focus changes.
|
||||||
|
*
|
||||||
|
* @param last_mon_num The index of the previously selected monitor
|
||||||
|
* @param new_mon_num The index of the newly selected monitor
|
||||||
|
*/
|
||||||
|
void ipc_monitor_focus_change_event(const int last_mon_num,
|
||||||
|
const int new_mon_num);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a focused_title_change_event to all subscribers. Should only be called
|
||||||
|
* if a selected client has a title change.
|
||||||
|
*
|
||||||
|
* @param mon_num Index of the client's monitor
|
||||||
|
* @param client_id Window XID of client
|
||||||
|
* @param old_name Old name of the client window
|
||||||
|
* @param new_name New name of the client window
|
||||||
|
*/
|
||||||
|
void ipc_focused_title_change_event(const int mon_num, const Window client_id,
|
||||||
|
const char *old_name, const char *new_name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a focused_state_change_event to all subscribers. Should only be called
|
||||||
|
* if a selected client has a state change.
|
||||||
|
*
|
||||||
|
* @param mon_num Index of the client's monitor
|
||||||
|
* @param client_id Window XID of client
|
||||||
|
* @param old_state Old state of the client
|
||||||
|
* @param new_state New state of the client
|
||||||
|
*/
|
||||||
|
void ipc_focused_state_change_event(const int mon_num, const Window client_id,
|
||||||
|
const ClientState *old_state,
|
||||||
|
const ClientState *new_state);
|
||||||
|
/**
|
||||||
|
* Check to see if an event has occured and call the *_change_event functions
|
||||||
|
* accordingly
|
||||||
|
*
|
||||||
|
* @param mons Address of Monitor pointing to start of linked list
|
||||||
|
* @param lastselmon Address of pointer to previously selected monitor
|
||||||
|
* @param selmon Address of selected Monitor
|
||||||
|
*/
|
||||||
|
void ipc_send_events(Monitor *mons, Monitor **lastselmon, Monitor *selmon);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle an epoll event caused by a registered IPC client. Read, process, and
|
||||||
|
* handle any received messages from clients. Write pending buffer to client if
|
||||||
|
* the client is ready to receive messages. Drop clients that have sent an
|
||||||
|
* EPOLLHUP.
|
||||||
|
*
|
||||||
|
* @param ev Associated epoll event returned by epoll_wait
|
||||||
|
* @param mons Address of Monitor pointing to start of linked list
|
||||||
|
* @param selmon Address of selected Monitor
|
||||||
|
* @param lastselmon Address of pointer to previously selected monitor
|
||||||
|
* @param tags Array of tag names
|
||||||
|
* @param tags_len Length of tags array
|
||||||
|
* @param layouts Array of available layouts
|
||||||
|
* @param layouts_len Length of layouts array
|
||||||
|
*
|
||||||
|
* @return 0 if event was successfully handled, -1 on any error receiving
|
||||||
|
* or handling incoming messages or unhandled epoll event.
|
||||||
|
*/
|
||||||
|
int ipc_handle_client_epoll_event(struct epoll_event *ev, Monitor *mons,
|
||||||
|
Monitor **lastselmon, Monitor *selmon,
|
||||||
|
const char *tags[], const int tags_len,
|
||||||
|
const Layout *layouts, const int layouts_len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle an epoll event caused by the IPC socket. This function only handles an
|
||||||
|
* EPOLLIN event indicating a new client requesting to connect to the socket.
|
||||||
|
*
|
||||||
|
* @param ev Associated epoll event returned by epoll_wait
|
||||||
|
*
|
||||||
|
* @return 0, if the event was successfully handled, -1 if not an EPOLLIN event
|
||||||
|
* or if a new IPC client connection request could not be accepted.
|
||||||
|
*/
|
||||||
|
int ipc_handle_socket_epoll_event(struct epoll_event *ev);
|
||||||
|
|
||||||
|
#endif /* IPC_H_ */
|
27
layouts.c
27
layouts.c
@ -1,27 +0,0 @@
|
|||||||
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++;
|
|
||||||
}
|
|
||||||
}
|
|
@ -46,3 +46,4 @@ movestack(const Arg *arg) {
|
|||||||
arrange(selmon);
|
arrange(selmon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
53
patches/dwm-actualfullscreen-20191112-cb3f58a.diff
Normal file
53
patches/dwm-actualfullscreen-20191112-cb3f58a.diff
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
From 3a16816a6f5d38014c2a06ce395873c545c8789a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Soenke Lambert <s.lambert@mittwald.de>
|
||||||
|
Date: Tue, 12 Nov 2019 10:44:02 +0100
|
||||||
|
Subject: [PATCH] Fullscreen current window with [Alt]+[Shift]+[f]
|
||||||
|
|
||||||
|
This actually fullscreens a window, instead of just hiding the statusbar
|
||||||
|
and applying the monocle layout.
|
||||||
|
---
|
||||||
|
config.def.h | 1 +
|
||||||
|
dwm.c | 8 ++++++++
|
||||||
|
2 files changed, 9 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 1c0b587..8cd3204 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -78,6 +78,7 @@ static Key keys[] = {
|
||||||
|
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
|
||||||
|
{ MODKEY, XK_space, setlayout, {0} },
|
||||||
|
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
||||||
|
+ { MODKEY|ShiftMask, XK_f, togglefullscr, {0} },
|
||||||
|
{ MODKEY, XK_0, view, {.ui = ~0 } },
|
||||||
|
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
|
||||||
|
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 4465af1..c1b899a 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -211,6 +211,7 @@ static void tagmon(const Arg *arg);
|
||||||
|
static void tile(Monitor *);
|
||||||
|
static void togglebar(const Arg *arg);
|
||||||
|
static void togglefloating(const Arg *arg);
|
||||||
|
+static void togglefullscr(const Arg *arg);
|
||||||
|
static void toggletag(const Arg *arg);
|
||||||
|
static void toggleview(const Arg *arg);
|
||||||
|
static void unfocus(Client *c, int setfocus);
|
||||||
|
@@ -1719,6 +1720,13 @@ togglefloating(const Arg *arg)
|
||||||
|
arrange(selmon);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+togglefullscr(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ if(selmon->sel)
|
||||||
|
+ setfullscreen(selmon->sel, !selmon->sel->isfullscreen);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
toggletag(const Arg *arg)
|
||||||
|
{
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
13
patches/dwm-alwaysfullscreen-6.1.diff
Normal file
13
patches/dwm-alwaysfullscreen-6.1.diff
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 0362114..a5cab76 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -847,7 +847,7 @@ focusstack(const Arg *arg)
|
||||||
|
{
|
||||||
|
Client *c = NULL, *i;
|
||||||
|
|
||||||
|
- if (!selmon->sel)
|
||||||
|
+ if (!selmon->sel || selmon->sel->isfullscreen)
|
||||||
|
return;
|
||||||
|
if (arg->i > 0) {
|
||||||
|
for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next);
|
446
patches/dwm-anybar-polybar-tray-fix-20200905-bb2e722.diff
Normal file
446
patches/dwm-anybar-polybar-tray-fix-20200905-bb2e722.diff
Normal file
@ -0,0 +1,446 @@
|
|||||||
|
From a046eabd24a430ee2a7348a807057dc7c42f7cec Mon Sep 17 00:00:00 2001
|
||||||
|
From: mihirlad55 <mihirlad55@gmail.com>
|
||||||
|
Date: Sat, 5 Sep 2020 00:51:33 +0000
|
||||||
|
Subject: [PATCH] Add support for managing external status bars
|
||||||
|
|
||||||
|
This patch allows dwm to manage other status bars such as
|
||||||
|
polybar/lemonbar without them needing to set override-redirect. For
|
||||||
|
all intents and purposes, DWM treats this bar as if it were its own
|
||||||
|
and as a result helps the status bar and DWM live in harmony.
|
||||||
|
|
||||||
|
This has a few advantages
|
||||||
|
* The bar does not block fullscreen windows
|
||||||
|
* DWM makes room for the status bar, so windows do not overlap the bar
|
||||||
|
* The bar can be hidden/killed and DWM will not keep an unsightly gap
|
||||||
|
where the bar was
|
||||||
|
* DWM receives EnterNotify events when your cursor enters the bar
|
||||||
|
|
||||||
|
To use another status bar, set usealtbar to 1 in your config.h and set
|
||||||
|
altbarclass to the class name (can be found using xprop) to the class
|
||||||
|
name of your status bar. Also make sure that if your status bar will
|
||||||
|
be displayed on top, topbar is set to 1 in your config, and if it will
|
||||||
|
be displayed on bottom, topbar is set to 0. This patch does not
|
||||||
|
support bars that are not docked at the top or at the bottom of your
|
||||||
|
monitor.
|
||||||
|
|
||||||
|
This verison of the patch fixes handling of polybar's tray.
|
||||||
|
|
||||||
|
The patch is developed at https://github.com/mihirlad55/dwm-anybar
|
||||||
|
---
|
||||||
|
config.def.h | 4 ++
|
||||||
|
dwm.c | 193 +++++++++++++++++++++++++++++++++++++++++++++++----
|
||||||
|
2 files changed, 182 insertions(+), 15 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 1c0b587..f45211b 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/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/dwm.c b/dwm.c
|
||||||
|
index 9fd0286..7bb5307 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/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)
|
||||||
|
@@ -116,7 +116,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;
|
||||||
|
@@ -129,6 +130,7 @@ struct Monitor {
|
||||||
|
Client *stack;
|
||||||
|
Monitor *next;
|
||||||
|
Window barwin;
|
||||||
|
+ Window traywin;
|
||||||
|
const Layout *lt[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -179,6 +181,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);
|
||||||
|
@@ -195,6 +199,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);
|
||||||
|
@@ -207,6 +212,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 *);
|
||||||
|
@@ -216,6 +222,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);
|
||||||
|
@@ -230,6 +238,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);
|
||||||
|
@@ -505,8 +514,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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -568,7 +579,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);
|
||||||
|
@@ -639,6 +650,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);
|
||||||
|
@@ -649,10 +661,15 @@ void
|
||||||
|
destroynotify(XEvent *e)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
+ Monitor *m;
|
||||||
|
XDestroyWindowEvent *ev = &e->xdestroywindow;
|
||||||
|
|
||||||
|
if ((c = wintoclient(ev->window)))
|
||||||
|
unmanage(c, 1);
|
||||||
|
+ else if (usealtbar && (m = wintomon(ev->window)) && m->barwin == ev->window)
|
||||||
|
+ unmanagealtbar(ev->window);
|
||||||
|
+ else if (usealtbar && m->traywin == ev->window)
|
||||||
|
+ unmanagetray(ev->window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
@@ -696,6 +713,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;
|
||||||
|
@@ -1077,6 +1097,45 @@ manage(Window w, XWindowAttributes *wa)
|
||||||
|
focus(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
+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
|
||||||
|
mappingnotify(XEvent *e)
|
||||||
|
{
|
||||||
|
@@ -1097,7 +1156,9 @@ maprequest(XEvent *e)
|
||||||
|
return;
|
||||||
|
if (wa.override_redirect)
|
||||||
|
return;
|
||||||
|
- if (!wintoclient(ev->window))
|
||||||
|
+ if (usealtbar && wmclasscontains(ev->window, altbarclass, ""))
|
||||||
|
+ managealtbar(ev->window, &wa);
|
||||||
|
+ else if (!wintoclient(ev->window))
|
||||||
|
manage(ev->window, &wa);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1393,7 +1454,9 @@ scan(void)
|
||||||
|
if (!XGetWindowAttributes(dpy, wins[i], &wa)
|
||||||
|
|| wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
|
||||||
|
continue;
|
||||||
|
- if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)
|
||||||
|
+ if (usealtbar && 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 */
|
||||||
|
@@ -1408,6 +1471,29 @@ 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)
|
||||||
|
{
|
||||||
|
@@ -1546,7 +1632,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);
|
||||||
|
@@ -1595,6 +1681,7 @@ setup(void)
|
||||||
|
XSelectInput(dpy, root, wa.event_mask);
|
||||||
|
grabkeys();
|
||||||
|
focus(NULL);
|
||||||
|
+ spawnbar();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1653,6 +1740,13 @@ spawn(const Arg *arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+spawnbar()
|
||||||
|
+{
|
||||||
|
+ if (*altbarcmd)
|
||||||
|
+ system(altbarcmd);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
tag(const Arg *arg)
|
||||||
|
{
|
||||||
|
@@ -1702,9 +1796,19 @@ 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 (usealtbar && !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);
|
||||||
|
+ if (usealtbar)
|
||||||
|
+ XMoveResizeWindow(dpy, selmon->traywin, selmon->tx, selmon->by, selmon->tw, selmon->bh);
|
||||||
|
arrange(selmon);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1787,10 +1891,41 @@ unmanage(Client *c, int destroyed)
|
||||||
|
arrange(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
+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
|
||||||
|
unmapnotify(XEvent *e)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
+ Monitor *m;
|
||||||
|
XUnmapEvent *ev = &e->xunmap;
|
||||||
|
|
||||||
|
if ((c = wintoclient(ev->window))) {
|
||||||
|
@@ -1798,12 +1933,18 @@ unmapnotify(XEvent *e)
|
||||||
|
setclientstate(c, WithdrawnState);
|
||||||
|
else
|
||||||
|
unmanage(c, 0);
|
||||||
|
- }
|
||||||
|
+ } else if (usealtbar && (m = wintomon(ev->window)) && m->barwin == ev->window)
|
||||||
|
+ unmanagealtbar(ev->window);
|
||||||
|
+ else if (usealtbar && m->traywin == ev->window)
|
||||||
|
+ unmanagetray(ev->window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
updatebars(void)
|
||||||
|
{
|
||||||
|
+ if (usealtbar)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
Monitor *m;
|
||||||
|
XSetWindowAttributes wa = {
|
||||||
|
.override_redirect = True,
|
||||||
|
@@ -1829,11 +1970,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
|
||||||
|
@@ -2070,13 +2211,35 @@ 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. */
|
||||||
|
--
|
||||||
|
2.28.0
|
||||||
|
|
56
patches/dwm-aspectresize-6.2.diff
Normal file
56
patches/dwm-aspectresize-6.2.diff
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 1c0b587..2fcc30d 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -72,6 +72,8 @@ static Key keys[] = {
|
||||||
|
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
|
||||||
|
{ MODKEY, XK_Return, zoom, {0} },
|
||||||
|
{ MODKEY, XK_Tab, view, {0} },
|
||||||
|
+ { MODKEY|ShiftMask, XK_j, aspectresize, {.i = +24} },
|
||||||
|
+ { MODKEY|ShiftMask, XK_k, aspectresize, {.i = -24} },
|
||||||
|
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
|
||||||
|
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
||||||
|
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 9fd0286..6a02119 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -146,6 +146,7 @@ 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 aspectresize(const Arg *arg);
|
||||||
|
static void attach(Client *c);
|
||||||
|
static void attachstack(Client *c);
|
||||||
|
static void buttonpress(XEvent *e);
|
||||||
|
@@ -400,6 +401,30 @@ arrangemon(Monitor *m)
|
||||||
|
m->lt[m->sellt]->arrange(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+aspectresize(const Arg *arg) {
|
||||||
|
+ /* only floating windows can be moved */
|
||||||
|
+ Client *c;
|
||||||
|
+ c = selmon->sel;
|
||||||
|
+ float ratio;
|
||||||
|
+ int w, h,nw, nh;
|
||||||
|
+
|
||||||
|
+ if (!c || !arg)
|
||||||
|
+ return;
|
||||||
|
+ if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ ratio = (float)c->w / (float)c->h;
|
||||||
|
+ h = arg->i;
|
||||||
|
+ w = (int)(ratio * h);
|
||||||
|
+
|
||||||
|
+ nw = c->w + w;
|
||||||
|
+ nh = c->h + h;
|
||||||
|
+
|
||||||
|
+ XRaiseWindow(dpy, c->win);
|
||||||
|
+ resize(c, c->x, c->y, nw, nh, True);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
attach(Client *c)
|
||||||
|
{
|
199
patches/dwm-attachbelow-toggleable-6.2.diff
Normal file
199
patches/dwm-attachbelow-toggleable-6.2.diff
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
From ee036687ed9e1bb973b9e34694a57cf5dd67652d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jonathan Hodgson <git@jonathanh.co.uk>
|
||||||
|
Date: Mon, 6 May 2019 18:34:40 +0100
|
||||||
|
Subject: [PATCH 1/4] Adds attach below option
|
||||||
|
|
||||||
|
---
|
||||||
|
config.def.h | 1 +
|
||||||
|
dwm.c | 31 ++++++++++++++++++++++++++++---
|
||||||
|
2 files changed, 29 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 1c0b587..51ad933 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -35,6 +35,7 @@ static const Rule rules[] = {
|
||||||
|
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 attachbelow = 1; /* 1 means attach at the end */
|
||||||
|
|
||||||
|
static const Layout layouts[] = {
|
||||||
|
/* symbol arrange function */
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 4465af1..bd715a2 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -147,6 +147,7 @@ static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interac
|
||||||
|
static void arrange(Monitor *m);
|
||||||
|
static void arrangemon(Monitor *m);
|
||||||
|
static void attach(Client *c);
|
||||||
|
+static void attachBelow(Client *c);
|
||||||
|
static void attachstack(Client *c);
|
||||||
|
static void buttonpress(XEvent *e);
|
||||||
|
static void checkotherwm(void);
|
||||||
|
@@ -405,6 +406,21 @@ attach(Client *c)
|
||||||
|
c->next = c->mon->clients;
|
||||||
|
c->mon->clients = c;
|
||||||
|
}
|
||||||
|
+void
|
||||||
|
+attachBelow(Client *c)
|
||||||
|
+{
|
||||||
|
+ //If there is nothing on the monitor or the selected client is floating, attach as normal
|
||||||
|
+ if(c->mon->sel == NULL || c->mon->sel == c || c->mon->sel->isfloating) {
|
||||||
|
+ attach(c);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ //Set the new client's next property to the same as the currently selected clients next
|
||||||
|
+ c->next = c->mon->sel->next;
|
||||||
|
+ //Set the currently selected clients next property to the new client
|
||||||
|
+ c->mon->sel->next = c;
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
|
||||||
|
void
|
||||||
|
attachstack(Client *c)
|
||||||
|
@@ -1062,7 +1078,10 @@ manage(Window w, XWindowAttributes *wa)
|
||||||
|
c->isfloating = c->oldstate = trans != None || c->isfixed;
|
||||||
|
if (c->isfloating)
|
||||||
|
XRaiseWindow(dpy, c->win);
|
||||||
|
- attach(c);
|
||||||
|
+ if( attachbelow )
|
||||||
|
+ attachBelow(c);
|
||||||
|
+ else
|
||||||
|
+ attach(c);
|
||||||
|
attachstack(c);
|
||||||
|
XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
|
||||||
|
(unsigned char *) &(c->win), 1);
|
||||||
|
@@ -1417,7 +1436,10 @@ sendmon(Client *c, Monitor *m)
|
||||||
|
detachstack(c);
|
||||||
|
c->mon = m;
|
||||||
|
c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
|
||||||
|
- attach(c);
|
||||||
|
+ if( attachbelow )
|
||||||
|
+ attachBelow(c);
|
||||||
|
+ else
|
||||||
|
+ attach(c);
|
||||||
|
attachstack(c);
|
||||||
|
focus(NULL);
|
||||||
|
arrange(NULL);
|
||||||
|
@@ -1897,7 +1919,10 @@ updategeom(void)
|
||||||
|
m->clients = c->next;
|
||||||
|
detachstack(c);
|
||||||
|
c->mon = mons;
|
||||||
|
- attach(c);
|
||||||
|
+ if( attachbelow )
|
||||||
|
+ attachBelow(c);
|
||||||
|
+ else
|
||||||
|
+ attach(c);
|
||||||
|
attachstack(c);
|
||||||
|
}
|
||||||
|
if (m == selmon)
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
||||||
|
|
||||||
|
From e212c1d8cbdcc56c33c717131dfa7c1689e27e9f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jonathan Hodgson <git@jonathanh.co.uk>
|
||||||
|
Date: Mon, 6 May 2019 19:27:57 +0100
|
||||||
|
Subject: [PATCH 2/4] fixes comment
|
||||||
|
|
||||||
|
---
|
||||||
|
config.def.h | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 51ad933..cb8053a 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -35,7 +35,7 @@ static const Rule rules[] = {
|
||||||
|
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 attachbelow = 1; /* 1 means attach at the end */
|
||||||
|
+static const int attachbelow = 1; /* 1 means attach after the currently active window */
|
||||||
|
|
||||||
|
static const Layout layouts[] = {
|
||||||
|
/* symbol arrange function */
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
||||||
|
|
||||||
|
From 7568ea3f8756e7e82b30c4943556ae646a445d1c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jonathan Hodgson <git@jonathanh.co.uk>
|
||||||
|
Date: Mon, 6 May 2019 20:00:30 +0100
|
||||||
|
Subject: [PATCH 3/4] Makes changes to man page to reflect attach below patch
|
||||||
|
|
||||||
|
---
|
||||||
|
dwm.1 | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/dwm.1 b/dwm.1
|
||||||
|
index 13b3729..fb6e76c 100644
|
||||||
|
--- a/dwm.1
|
||||||
|
+++ b/dwm.1
|
||||||
|
@@ -29,6 +29,9 @@ color. The tags of the focused window are indicated with a filled square in the
|
||||||
|
top left corner. The tags which are applied to one or more windows are
|
||||||
|
indicated with an empty square in the top left corner.
|
||||||
|
.P
|
||||||
|
+The attach below patch makes newly spawned windows attach after the currently
|
||||||
|
+selected window
|
||||||
|
+.P
|
||||||
|
dwm draws a small border around windows to indicate the focus state.
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
||||||
|
|
||||||
|
From 362b95a5b9f91673f27f3e3343b5738df3c9d6e9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jonathan Hodgson <git@jonathanh.co.uk>
|
||||||
|
Date: Sun, 2 Jun 2019 15:11:57 +0100
|
||||||
|
Subject: [PATCH 4/4] Allows attach below to be toggled
|
||||||
|
|
||||||
|
---
|
||||||
|
config.def.h | 2 +-
|
||||||
|
dwm.c | 6 ++++++
|
||||||
|
2 files changed, 7 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index cb8053a..b4d35aa 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -35,7 +35,7 @@ static const Rule rules[] = {
|
||||||
|
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 attachbelow = 1; /* 1 means attach after the currently active window */
|
||||||
|
+static int attachbelow = 1; /* 1 means attach after the currently active window */
|
||||||
|
|
||||||
|
static const Layout layouts[] = {
|
||||||
|
/* symbol arrange function */
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index bd715a2..5d88653 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -148,6 +148,7 @@ static void arrange(Monitor *m);
|
||||||
|
static void arrangemon(Monitor *m);
|
||||||
|
static void attach(Client *c);
|
||||||
|
static void attachBelow(Client *c);
|
||||||
|
+static void toggleAttachBelow();
|
||||||
|
static void attachstack(Client *c);
|
||||||
|
static void buttonpress(XEvent *e);
|
||||||
|
static void checkotherwm(void);
|
||||||
|
@@ -422,6 +423,11 @@ attachBelow(Client *c)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
+void toggleAttachBelow()
|
||||||
|
+{
|
||||||
|
+ attachbelow = !attachbelow;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
attachstack(Client *c)
|
||||||
|
{
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
35
patches/dwm-autoresize-6.1.diff
Normal file
35
patches/dwm-autoresize-6.1.diff
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 0362114..e4e8514 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -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, needresize;
|
||||||
|
Client *next;
|
||||||
|
Client *snext;
|
||||||
|
Monitor *mon;
|
||||||
|
@@ -621,6 +621,8 @@ configurerequest(XEvent *e)
|
||||||
|
configure(c);
|
||||||
|
if (ISVISIBLE(c))
|
||||||
|
XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
|
||||||
|
+ else
|
||||||
|
+ c->needresize = 1;
|
||||||
|
} else
|
||||||
|
configure(c);
|
||||||
|
} else {
|
||||||
|
@@ -1611,6 +1613,12 @@ showhide(Client *c)
|
||||||
|
if (ISVISIBLE(c)) {
|
||||||
|
/* show clients top down */
|
||||||
|
XMoveWindow(dpy, c->win, c->x, c->y);
|
||||||
|
+ if (c->needresize) {
|
||||||
|
+ c->needresize = 0;
|
||||||
|
+ XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
|
||||||
|
+ } else {
|
||||||
|
+ XMoveWindow(dpy, c->win, c->x, c->y);
|
||||||
|
+ }
|
||||||
|
if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen)
|
||||||
|
resize(c, c->x, c->y, c->w, c->h, 0);
|
||||||
|
showhide(c->snext);
|
90
patches/dwm-center-6.2.diff
Normal file
90
patches/dwm-center-6.2.diff
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
From 69f91089d9248fa9695eb925956e255a215171b8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: bakkeby <bakkeby@gmail.com>
|
||||||
|
Date: Tue, 7 Apr 2020 12:29:08 +0200
|
||||||
|
Subject: [PATCH] Adding 6.2 center patch with multi-monitor fix and
|
||||||
|
auto-centering of floating popup windows
|
||||||
|
---
|
||||||
|
config.def.h | 6 +++---
|
||||||
|
dwm.c | 13 +++++++++++--
|
||||||
|
2 files changed, 14 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 1c0b587..44b46e5 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -26,9 +26,9 @@ static const Rule rules[] = {
|
||||||
|
* WM_CLASS(STRING) = instance, class
|
||||||
|
* WM_NAME(STRING) = title
|
||||||
|
*/
|
||||||
|
- /* class instance title tags mask isfloating monitor */
|
||||||
|
- { "Gimp", NULL, NULL, 0, 1, -1 },
|
||||||
|
- { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
|
||||||
|
+ /* class instance title tags mask iscentered isfloating monitor */
|
||||||
|
+ { "Gimp", NULL, NULL, 0, 0, 1, -1 },
|
||||||
|
+ { "Firefox", NULL, NULL, 1 << 8, 0, 0, -1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* layout(s) */
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 4465af1..ab33757 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -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, iscentered, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
|
||||||
|
Client *next;
|
||||||
|
Client *snext;
|
||||||
|
Monitor *mon;
|
||||||
|
@@ -137,6 +137,7 @@ typedef struct {
|
||||||
|
const char *instance;
|
||||||
|
const char *title;
|
||||||
|
unsigned int tags;
|
||||||
|
+ int iscentered;
|
||||||
|
int isfloating;
|
||||||
|
int monitor;
|
||||||
|
} Rule;
|
||||||
|
@@ -285,6 +286,7 @@ applyrules(Client *c)
|
||||||
|
XClassHint ch = { NULL, NULL };
|
||||||
|
|
||||||
|
/* rule matching */
|
||||||
|
+ c->iscentered = 0;
|
||||||
|
c->isfloating = 0;
|
||||||
|
c->tags = 0;
|
||||||
|
XGetClassHint(dpy, c->win, &ch);
|
||||||
|
@@ -297,6 +299,7 @@ applyrules(Client *c)
|
||||||
|
&& (!r->class || strstr(class, r->class))
|
||||||
|
&& (!r->instance || strstr(instance, r->instance)))
|
||||||
|
{
|
||||||
|
+ c->iscentered = r->iscentered;
|
||||||
|
c->isfloating = r->isfloating;
|
||||||
|
c->tags |= r->tags;
|
||||||
|
for (m = mons; m && m->num != r->monitor; m = m->next);
|
||||||
|
@@ -1056,6 +1059,10 @@ manage(Window w, XWindowAttributes *wa)
|
||||||
|
updatewindowtype(c);
|
||||||
|
updatesizehints(c);
|
||||||
|
updatewmhints(c);
|
||||||
|
+ if (c->iscentered) {
|
||||||
|
+ 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)
|
||||||
|
@@ -2009,8 +2016,10 @@ updatewindowtype(Client *c)
|
||||||
|
|
||||||
|
if (state == netatom[NetWMFullscreen])
|
||||||
|
setfullscreen(c, 1);
|
||||||
|
- if (wtype == netatom[NetWMWindowTypeDialog])
|
||||||
|
+ if (wtype == netatom[NetWMWindowTypeDialog]) {
|
||||||
|
+ c->iscentered = 1;
|
||||||
|
c->isfloating = 1;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
--
|
||||||
|
2.17.1
|
||||||
|
|
117
patches/dwm-cfacts-20200913-61bb8b2.diff
Normal file
117
patches/dwm-cfacts-20200913-61bb8b2.diff
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
From c32a879432573d71dec7fcb4bf68927d2f4cdf10 Mon Sep 17 00:00:00 2001
|
||||||
|
From: iofq <cjriddz@protonmail.com>
|
||||||
|
Date: Sat, 12 Sep 2020 22:28:09 -0500
|
||||||
|
Subject: [PATCH] Fixed 'cfacts' patch failure due to upstream commit
|
||||||
|
'f09418bbb...'
|
||||||
|
|
||||||
|
---
|
||||||
|
config.def.h | 3 +++
|
||||||
|
dwm.c | 34 +++++++++++++++++++++++++++++++---
|
||||||
|
2 files changed, 34 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 1c0b587..83910c1 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -70,6 +70,9 @@ 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_h, setcfact, {.f = +0.25} },
|
||||||
|
+ { MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} },
|
||||||
|
+ { MODKEY|ShiftMask, XK_o, setcfact, {.f = 0.00} },
|
||||||
|
{ MODKEY, XK_Return, zoom, {0} },
|
||||||
|
{ MODKEY, XK_Tab, view, {0} },
|
||||||
|
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 664c527..5233229 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -87,6 +87,7 @@ typedef struct Client Client;
|
||||||
|
struct Client {
|
||||||
|
char name[256];
|
||||||
|
float mina, maxa;
|
||||||
|
+ float cfact;
|
||||||
|
int x, y, w, h;
|
||||||
|
int oldx, oldy, oldw, oldh;
|
||||||
|
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
|
||||||
|
@@ -201,6 +202,7 @@ static void setclientstate(Client *c, long state);
|
||||||
|
static void setfocus(Client *c);
|
||||||
|
static void setfullscreen(Client *c, int fullscreen);
|
||||||
|
static void setlayout(const Arg *arg);
|
||||||
|
+static void setcfact(const Arg *arg);
|
||||||
|
static void setmfact(const Arg *arg);
|
||||||
|
static void setup(void);
|
||||||
|
static void seturgent(Client *c, int urg);
|
||||||
|
@@ -1030,6 +1032,7 @@ manage(Window w, XWindowAttributes *wa)
|
||||||
|
c->w = c->oldw = wa->width;
|
||||||
|
c->h = c->oldh = wa->height;
|
||||||
|
c->oldbw = wa->border_width;
|
||||||
|
+ c->cfact = 1.0;
|
||||||
|
|
||||||
|
updatetitle(c);
|
||||||
|
if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
|
||||||
|
@@ -1512,6 +1515,23 @@ setlayout(const Arg *arg)
|
||||||
|
drawbar(selmon);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void setcfact(const Arg *arg) {
|
||||||
|
+ float f;
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ c = selmon->sel;
|
||||||
|
+
|
||||||
|
+ if(!arg || !c || !selmon->lt[selmon->sellt]->arrange)
|
||||||
|
+ return;
|
||||||
|
+ f = arg->f + c->cfact;
|
||||||
|
+ if(arg->f == 0.0)
|
||||||
|
+ f = 1.0;
|
||||||
|
+ else if(f < 0.25 || f > 4.0)
|
||||||
|
+ return;
|
||||||
|
+ c->cfact = f;
|
||||||
|
+ arrange(selmon);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* arg > 1.0 will set mfact absolutely */
|
||||||
|
void
|
||||||
|
setmfact(const Arg *arg)
|
||||||
|
@@ -1675,9 +1695,15 @@ void
|
||||||
|
tile(Monitor *m)
|
||||||
|
{
|
||||||
|
unsigned int i, n, h, mw, my, ty;
|
||||||
|
+ float mfacts = 0, sfacts = 0;
|
||||||
|
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 < m->nmaster)
|
||||||
|
+ mfacts += c->cfact;
|
||||||
|
+ else
|
||||||
|
+ sfacts += c->cfact;
|
||||||
|
+ }
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
@@ -1687,15 +1713,17 @@ tile(Monitor *m)
|
||||||
|
mw = m->ww;
|
||||||
|
for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
|
if (i < m->nmaster) {
|
||||||
|
- h = (m->wh - my) / (MIN(n, m->nmaster) - i);
|
||||||
|
+ h = (m->wh - my) * (c->cfact / mfacts);
|
||||||
|
resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
|
||||||
|
if (my + HEIGHT(c) < m->wh)
|
||||||
|
my += HEIGHT(c);
|
||||||
|
+ mfacts -= c->cfact;
|
||||||
|
} else {
|
||||||
|
- h = (m->wh - ty) / (n - i);
|
||||||
|
+ h = (m->wh - ty) * (c->cfact / sfacts);
|
||||||
|
resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
|
||||||
|
if (ty + HEIGHT(c) < m->wh)
|
||||||
|
ty += HEIGHT(c);
|
||||||
|
+ sfacts -= c->cfact;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.28.0
|
||||||
|
|
992
patches/dwm-cfacts-vanitygaps-6.2.diff
Normal file
992
patches/dwm-cfacts-vanitygaps-6.2.diff
Normal file
@ -0,0 +1,992 @@
|
|||||||
|
From 051e4de72079bb0b8e50d2faa61b9a0ef36434b5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: bakkeby <bakkeby@gmail.com>
|
||||||
|
Date: Fri, 8 May 2020 16:51:00 +0200
|
||||||
|
Subject: [PATCH 2/2] vanitygaps - adds gaps to layouts
|
||||||
|
|
||||||
|
This patch differentiates between inner and outer gaps as well as
|
||||||
|
horizontal and vertical gaps.
|
||||||
|
|
||||||
|
The logic of these layouts also aims to be pixel perfect by ensuring
|
||||||
|
an even split of the available space and re-distributing the remainder
|
||||||
|
among the available clients.
|
||||||
|
---
|
||||||
|
config.def.h | 38 ++-
|
||||||
|
dwm.c | 43 +--
|
||||||
|
vanitygaps.c | 822 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
3 files changed, 867 insertions(+), 36 deletions(-)
|
||||||
|
create mode 100644 vanitygaps.c
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 83910c1..91a9cfc 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -3,6 +3,11 @@
|
||||||
|
/* appearance */
|
||||||
|
static const unsigned int borderpx = 1; /* border pixel of windows */
|
||||||
|
static const unsigned int snap = 32; /* snap pixel */
|
||||||
|
+static const unsigned int gappih = 20; /* horiz inner gap between windows */
|
||||||
|
+static const unsigned int gappiv = 10; /* vert inner gap between windows */
|
||||||
|
+static const unsigned int gappoh = 10; /* horiz outer gap between windows and screen edge */
|
||||||
|
+static const unsigned int gappov = 30; /* vert outer gap between windows and screen edge */
|
||||||
|
+static int smartgaps = 0; /* 1 means no outer gap when there is only one window */
|
||||||
|
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" };
|
||||||
|
@@ -36,11 +41,26 @@ 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 */
|
||||||
|
|
||||||
|
+#define FORCE_VSPLIT 1 /* nrowgrid layout: force two clients to always split vertically */
|
||||||
|
+#include "vanitygaps.c"
|
||||||
|
+
|
||||||
|
static const Layout layouts[] = {
|
||||||
|
/* symbol arrange function */
|
||||||
|
{ "[]=", tile }, /* first entry is default */
|
||||||
|
- { "><>", NULL }, /* no layout function means floating behavior */
|
||||||
|
{ "[M]", monocle },
|
||||||
|
+ { "[@]", spiral },
|
||||||
|
+ { "[\\]", dwindle },
|
||||||
|
+ { "H[]", deck },
|
||||||
|
+ { "TTT", bstack },
|
||||||
|
+ { "===", bstackhoriz },
|
||||||
|
+ { "HHH", grid },
|
||||||
|
+ { "###", nrowgrid },
|
||||||
|
+ { "---", horizgrid },
|
||||||
|
+ { ":::", gaplessgrid },
|
||||||
|
+ { "|M|", centeredmaster },
|
||||||
|
+ { ">M>", centeredfloatingmaster },
|
||||||
|
+ { "><>", NULL }, /* no layout function means floating behavior */
|
||||||
|
+ { NULL, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* key definitions */
|
||||||
|
@@ -74,6 +94,22 @@ static Key keys[] = {
|
||||||
|
{ MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} },
|
||||||
|
{ MODKEY|ShiftMask, XK_o, setcfact, {.f = 0.00} },
|
||||||
|
{ MODKEY, XK_Return, zoom, {0} },
|
||||||
|
+ { MODKEY|Mod4Mask, XK_u, incrgaps, {.i = +1 } },
|
||||||
|
+ { MODKEY|Mod4Mask|ShiftMask, XK_u, incrgaps, {.i = -1 } },
|
||||||
|
+ { MODKEY|Mod4Mask, XK_i, incrigaps, {.i = +1 } },
|
||||||
|
+ { MODKEY|Mod4Mask|ShiftMask, XK_i, incrigaps, {.i = -1 } },
|
||||||
|
+ { MODKEY|Mod4Mask, XK_o, incrogaps, {.i = +1 } },
|
||||||
|
+ { MODKEY|Mod4Mask|ShiftMask, XK_o, incrogaps, {.i = -1 } },
|
||||||
|
+ { MODKEY|Mod4Mask, XK_6, incrihgaps, {.i = +1 } },
|
||||||
|
+ { MODKEY|Mod4Mask|ShiftMask, XK_6, incrihgaps, {.i = -1 } },
|
||||||
|
+ { MODKEY|Mod4Mask, XK_7, incrivgaps, {.i = +1 } },
|
||||||
|
+ { MODKEY|Mod4Mask|ShiftMask, XK_7, incrivgaps, {.i = -1 } },
|
||||||
|
+ { MODKEY|Mod4Mask, XK_8, incrohgaps, {.i = +1 } },
|
||||||
|
+ { MODKEY|Mod4Mask|ShiftMask, XK_8, incrohgaps, {.i = -1 } },
|
||||||
|
+ { MODKEY|Mod4Mask, XK_9, incrovgaps, {.i = +1 } },
|
||||||
|
+ { MODKEY|Mod4Mask|ShiftMask, XK_9, incrovgaps, {.i = -1 } },
|
||||||
|
+ { MODKEY|Mod4Mask, XK_0, togglegaps, {0} },
|
||||||
|
+ { MODKEY|Mod4Mask|ShiftMask, XK_0, defaultgaps, {0} },
|
||||||
|
{ MODKEY, XK_Tab, view, {0} },
|
||||||
|
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
|
||||||
|
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 5592c57..7d503cb 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -120,6 +120,10 @@ struct Monitor {
|
||||||
|
int by; /* bar geometry */
|
||||||
|
int mx, my, mw, mh; /* screen size */
|
||||||
|
int wx, wy, ww, wh; /* window area */
|
||||||
|
+ int gappih; /* horizontal gap between windows */
|
||||||
|
+ int gappiv; /* vertical gap between windows */
|
||||||
|
+ int gappoh; /* horizontal outer gaps */
|
||||||
|
+ int gappov; /* vertical outer gaps */
|
||||||
|
unsigned int seltags;
|
||||||
|
unsigned int sellt;
|
||||||
|
unsigned int tagset[2];
|
||||||
|
@@ -210,7 +214,6 @@ static void sigchld(int unused);
|
||||||
|
static void spawn(const Arg *arg);
|
||||||
|
static void tag(const Arg *arg);
|
||||||
|
static void tagmon(const Arg *arg);
|
||||||
|
-static void tile(Monitor *);
|
||||||
|
static void togglebar(const Arg *arg);
|
||||||
|
static void togglefloating(const Arg *arg);
|
||||||
|
static void toggletag(const Arg *arg);
|
||||||
|
@@ -640,6 +643,10 @@ createmon(void)
|
||||||
|
m->nmaster = nmaster;
|
||||||
|
m->showbar = showbar;
|
||||||
|
m->topbar = topbar;
|
||||||
|
+ m->gappih = gappih;
|
||||||
|
+ m->gappiv = gappiv;
|
||||||
|
+ m->gappoh = gappoh;
|
||||||
|
+ m->gappov = gappov;
|
||||||
|
m->lt[0] = &layouts[0];
|
||||||
|
m->lt[1] = &layouts[1 % LENGTH(layouts)];
|
||||||
|
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
|
||||||
|
@@ -1691,40 +1698,6 @@ tagmon(const Arg *arg)
|
||||||
|
sendmon(selmon->sel, dirtomon(arg->i));
|
||||||
|
}
|
||||||
|
|
||||||
|
-void
|
||||||
|
-tile(Monitor *m)
|
||||||
|
-{
|
||||||
|
- unsigned int i, n, h, mw, my, ty;
|
||||||
|
- float mfacts = 0, sfacts = 0;
|
||||||
|
- Client *c;
|
||||||
|
-
|
||||||
|
- for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) {
|
||||||
|
- if (n < m->nmaster)
|
||||||
|
- mfacts += c->cfact;
|
||||||
|
- else
|
||||||
|
- sfacts += c->cfact;
|
||||||
|
- }
|
||||||
|
- if (n == 0)
|
||||||
|
- return;
|
||||||
|
-
|
||||||
|
- if (n > m->nmaster)
|
||||||
|
- mw = m->nmaster ? m->ww * m->mfact : 0;
|
||||||
|
- else
|
||||||
|
- mw = m->ww;
|
||||||
|
- for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
|
- if (i < m->nmaster) {
|
||||||
|
- h = (m->wh - my) * (c->cfact / mfacts);
|
||||||
|
- resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
|
||||||
|
- my += HEIGHT(c);
|
||||||
|
- mfacts -= c->cfact;
|
||||||
|
- } else {
|
||||||
|
- h = (m->wh - ty) * (c->cfact / sfacts);
|
||||||
|
- resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
|
||||||
|
- ty += HEIGHT(c);
|
||||||
|
- sfacts -= c->cfact;
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
void
|
||||||
|
togglebar(const Arg *arg)
|
||||||
|
{
|
||||||
|
diff --git a/vanitygaps.c b/vanitygaps.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..1a816b6
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/vanitygaps.c
|
||||||
|
@@ -0,0 +1,822 @@
|
||||||
|
+/* Key binding functions */
|
||||||
|
+static void defaultgaps(const Arg *arg);
|
||||||
|
+static void incrgaps(const Arg *arg);
|
||||||
|
+static void incrigaps(const Arg *arg);
|
||||||
|
+static void incrogaps(const Arg *arg);
|
||||||
|
+static void incrohgaps(const Arg *arg);
|
||||||
|
+static void incrovgaps(const Arg *arg);
|
||||||
|
+static void incrihgaps(const Arg *arg);
|
||||||
|
+static void incrivgaps(const Arg *arg);
|
||||||
|
+static void togglegaps(const Arg *arg);
|
||||||
|
+/* Layouts (delete the ones you do not need) */
|
||||||
|
+static void bstack(Monitor *m);
|
||||||
|
+static void bstackhoriz(Monitor *m);
|
||||||
|
+static void centeredmaster(Monitor *m);
|
||||||
|
+static void centeredfloatingmaster(Monitor *m);
|
||||||
|
+static void deck(Monitor *m);
|
||||||
|
+static void dwindle(Monitor *m);
|
||||||
|
+static void fibonacci(Monitor *m, int s);
|
||||||
|
+static void grid(Monitor *m);
|
||||||
|
+static void nrowgrid(Monitor *m);
|
||||||
|
+static void spiral(Monitor *m);
|
||||||
|
+static void tile(Monitor *m);
|
||||||
|
+/* Internals */
|
||||||
|
+static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc);
|
||||||
|
+static void getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr);
|
||||||
|
+static void setgaps(int oh, int ov, int ih, int iv);
|
||||||
|
+
|
||||||
|
+/* Settings */
|
||||||
|
+#if !PERTAG_PATCH
|
||||||
|
+static int enablegaps = 1;
|
||||||
|
+#endif // PERTAG_PATCH
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+setgaps(int oh, int ov, int ih, int iv)
|
||||||
|
+{
|
||||||
|
+ if (oh < 0) oh = 0;
|
||||||
|
+ if (ov < 0) ov = 0;
|
||||||
|
+ if (ih < 0) ih = 0;
|
||||||
|
+ if (iv < 0) iv = 0;
|
||||||
|
+
|
||||||
|
+ selmon->gappoh = oh;
|
||||||
|
+ selmon->gappov = ov;
|
||||||
|
+ selmon->gappih = ih;
|
||||||
|
+ selmon->gappiv = iv;
|
||||||
|
+ arrange(selmon);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+togglegaps(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ #if PERTAG_PATCH
|
||||||
|
+ selmon->pertag->enablegaps[selmon->pertag->curtag] = !selmon->pertag->enablegaps[selmon->pertag->curtag];
|
||||||
|
+ #else
|
||||||
|
+ enablegaps = !enablegaps;
|
||||||
|
+ #endif // PERTAG_PATCH
|
||||||
|
+ arrange(NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+defaultgaps(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ setgaps(gappoh, gappov, gappih, gappiv);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+incrgaps(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ setgaps(
|
||||||
|
+ selmon->gappoh + arg->i,
|
||||||
|
+ selmon->gappov + arg->i,
|
||||||
|
+ selmon->gappih + arg->i,
|
||||||
|
+ selmon->gappiv + arg->i
|
||||||
|
+ );
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+incrigaps(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ setgaps(
|
||||||
|
+ selmon->gappoh,
|
||||||
|
+ selmon->gappov,
|
||||||
|
+ selmon->gappih + arg->i,
|
||||||
|
+ selmon->gappiv + arg->i
|
||||||
|
+ );
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+incrogaps(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ setgaps(
|
||||||
|
+ selmon->gappoh + arg->i,
|
||||||
|
+ selmon->gappov + arg->i,
|
||||||
|
+ selmon->gappih,
|
||||||
|
+ selmon->gappiv
|
||||||
|
+ );
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+incrohgaps(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ setgaps(
|
||||||
|
+ selmon->gappoh + arg->i,
|
||||||
|
+ selmon->gappov,
|
||||||
|
+ selmon->gappih,
|
||||||
|
+ selmon->gappiv
|
||||||
|
+ );
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+incrovgaps(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ setgaps(
|
||||||
|
+ selmon->gappoh,
|
||||||
|
+ selmon->gappov + arg->i,
|
||||||
|
+ selmon->gappih,
|
||||||
|
+ selmon->gappiv
|
||||||
|
+ );
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+incrihgaps(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ setgaps(
|
||||||
|
+ selmon->gappoh,
|
||||||
|
+ selmon->gappov,
|
||||||
|
+ selmon->gappih + arg->i,
|
||||||
|
+ selmon->gappiv
|
||||||
|
+ );
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+incrivgaps(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ setgaps(
|
||||||
|
+ selmon->gappoh,
|
||||||
|
+ selmon->gappov,
|
||||||
|
+ selmon->gappih,
|
||||||
|
+ selmon->gappiv + arg->i
|
||||||
|
+ );
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc)
|
||||||
|
+{
|
||||||
|
+ unsigned int n, oe, ie;
|
||||||
|
+ #if PERTAG_PATCH
|
||||||
|
+ oe = ie = selmon->pertag->enablegaps[selmon->pertag->curtag];
|
||||||
|
+ #else
|
||||||
|
+ oe = ie = enablegaps;
|
||||||
|
+ #endif // PERTAG_PATCH
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
|
||||||
|
+ if (smartgaps && n == 1) {
|
||||||
|
+ oe = 0; // outer gaps disabled when only one client
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *oh = m->gappoh*oe; // outer horizontal gap
|
||||||
|
+ *ov = m->gappov*oe; // outer vertical gap
|
||||||
|
+ *ih = m->gappih*ie; // inner horizontal gap
|
||||||
|
+ *iv = m->gappiv*ie; // inner vertical gap
|
||||||
|
+ *nc = n; // number of clients
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr)
|
||||||
|
+{
|
||||||
|
+ unsigned int n;
|
||||||
|
+ float mfacts = 0, sfacts = 0;
|
||||||
|
+ int mtotal = 0, stotal = 0;
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
|
||||||
|
+ if (n < m->nmaster)
|
||||||
|
+ mfacts += c->cfact;
|
||||||
|
+ else
|
||||||
|
+ sfacts += c->cfact;
|
||||||
|
+
|
||||||
|
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
|
||||||
|
+ if (n < m->nmaster)
|
||||||
|
+ mtotal += msize * (c->cfact / mfacts);
|
||||||
|
+ else
|
||||||
|
+ stotal += ssize * (c->cfact / sfacts);
|
||||||
|
+
|
||||||
|
+ *mf = mfacts; // total factor of master area
|
||||||
|
+ *sf = sfacts; // total factor of stack area
|
||||||
|
+ *mr = msize - mtotal; // the remainder (rest) of pixels after a cfacts master split
|
||||||
|
+ *sr = ssize - stotal; // the remainder (rest) of pixels after a cfacts stack split
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/***
|
||||||
|
+ * Layouts
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Bottomstack layout + gaps
|
||||||
|
+ * https://dwm.suckless.org/patches/bottomstack/
|
||||||
|
+ */
|
||||||
|
+static void
|
||||||
|
+bstack(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ unsigned int i, n;
|
||||||
|
+ int oh, ov, ih, iv;
|
||||||
|
+ int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
+ int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
+ float mfacts, sfacts;
|
||||||
|
+ int mrest, srest;
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
+ if (n == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ sx = mx = m->wx + ov;
|
||||||
|
+ sy = my = m->wy + oh;
|
||||||
|
+ sh = mh = m->wh - 2*oh;
|
||||||
|
+ mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
|
||||||
|
+ sw = m->ww - 2*ov - iv * (n - m->nmaster - 1);
|
||||||
|
+
|
||||||
|
+ if (m->nmaster && n > m->nmaster) {
|
||||||
|
+ sh = (mh - ih) * (1 - m->mfact);
|
||||||
|
+ mh = mh - ih - sh;
|
||||||
|
+ sx = mx;
|
||||||
|
+ sy = my + mh + ih;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
|
||||||
|
+
|
||||||
|
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
|
||||||
|
+ if (i < m->nmaster) {
|
||||||
|
+ resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
|
||||||
|
+ mx += WIDTH(c) + iv;
|
||||||
|
+ } else {
|
||||||
|
+ resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
|
||||||
|
+ sx += WIDTH(c) + iv;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+bstackhoriz(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ unsigned int i, n;
|
||||||
|
+ int oh, ov, ih, iv;
|
||||||
|
+ int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
+ int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
+ float mfacts, sfacts;
|
||||||
|
+ int mrest, srest;
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
+ if (n == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ sx = mx = m->wx + ov;
|
||||||
|
+ sy = my = m->wy + oh;
|
||||||
|
+ mh = m->wh - 2*oh;
|
||||||
|
+ sh = m->wh - 2*oh - ih * (n - m->nmaster - 1);
|
||||||
|
+ mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
|
||||||
|
+ sw = m->ww - 2*ov;
|
||||||
|
+
|
||||||
|
+ if (m->nmaster && n > m->nmaster) {
|
||||||
|
+ sh = (mh - ih) * (1 - m->mfact);
|
||||||
|
+ mh = mh - ih - sh;
|
||||||
|
+ sy = my + mh + ih;
|
||||||
|
+ sh = m->wh - mh - 2*oh - ih * (n - m->nmaster);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ getfacts(m, mw, sh, &mfacts, &sfacts, &mrest, &srest);
|
||||||
|
+
|
||||||
|
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
|
||||||
|
+ if (i < m->nmaster) {
|
||||||
|
+ resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
|
||||||
|
+ mx += WIDTH(c) + iv;
|
||||||
|
+ } else {
|
||||||
|
+ resize(c, sx, sy, sw - (2*c->bw), sh * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
+ sy += HEIGHT(c) + ih;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Centred master layout + gaps
|
||||||
|
+ * https://dwm.suckless.org/patches/centeredmaster/
|
||||||
|
+ */
|
||||||
|
+void
|
||||||
|
+centeredmaster(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ unsigned int i, n;
|
||||||
|
+ int oh, ov, ih, iv;
|
||||||
|
+ int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
+ int lx = 0, ly = 0, lw = 0, lh = 0;
|
||||||
|
+ int rx = 0, ry = 0, rw = 0, rh = 0;
|
||||||
|
+ float mfacts = 0, lfacts = 0, rfacts = 0;
|
||||||
|
+ int mtotal = 0, ltotal = 0, rtotal = 0;
|
||||||
|
+ int mrest = 0, lrest = 0, rrest = 0;
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
+ if (n == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /* initialize areas */
|
||||||
|
+ mx = m->wx + ov;
|
||||||
|
+ my = m->wy + oh;
|
||||||
|
+ mh = m->wh - 2*oh - ih * ((!m->nmaster ? n : MIN(n, m->nmaster)) - 1);
|
||||||
|
+ mw = m->ww - 2*ov;
|
||||||
|
+ lh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - 1);
|
||||||
|
+ rh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - ((n - m->nmaster) % 2 ? 0 : 1));
|
||||||
|
+
|
||||||
|
+ if (m->nmaster && n > m->nmaster) {
|
||||||
|
+ /* go mfact box in the center if more than nmaster clients */
|
||||||
|
+ if (n - m->nmaster > 1) {
|
||||||
|
+ /* ||<-S->|<---M--->|<-S->|| */
|
||||||
|
+ mw = (m->ww - 2*ov - 2*iv) * m->mfact;
|
||||||
|
+ lw = (m->ww - mw - 2*ov - 2*iv) / 2;
|
||||||
|
+ rw = (m->ww - mw - 2*ov - 2*iv) - lw;
|
||||||
|
+ mx += lw + iv;
|
||||||
|
+ } else {
|
||||||
|
+ /* ||<---M--->|<-S->|| */
|
||||||
|
+ mw = (mw - iv) * m->mfact;
|
||||||
|
+ lw = 0;
|
||||||
|
+ rw = m->ww - mw - iv - 2*ov;
|
||||||
|
+ }
|
||||||
|
+ lx = m->wx + ov;
|
||||||
|
+ ly = m->wy + oh;
|
||||||
|
+ rx = mx + mw + iv;
|
||||||
|
+ ry = m->wy + oh;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* calculate facts */
|
||||||
|
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) {
|
||||||
|
+ if (!m->nmaster || n < m->nmaster)
|
||||||
|
+ mfacts += c->cfact;
|
||||||
|
+ else if ((n - m->nmaster) % 2)
|
||||||
|
+ lfacts += c->cfact; // total factor of left hand stack area
|
||||||
|
+ else
|
||||||
|
+ rfacts += c->cfact; // total factor of right hand stack area
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
|
||||||
|
+ if (!m->nmaster || n < m->nmaster)
|
||||||
|
+ mtotal += mh * (c->cfact / mfacts);
|
||||||
|
+ else if ((n - m->nmaster) % 2)
|
||||||
|
+ ltotal += lh * (c->cfact / lfacts);
|
||||||
|
+ else
|
||||||
|
+ rtotal += rh * (c->cfact / rfacts);
|
||||||
|
+
|
||||||
|
+ mrest = mh - mtotal;
|
||||||
|
+ lrest = lh - ltotal;
|
||||||
|
+ rrest = rh - rtotal;
|
||||||
|
+
|
||||||
|
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
|
||||||
|
+ if (!m->nmaster || i < m->nmaster) {
|
||||||
|
+ /* nmaster clients are stacked vertically, in the center of the screen */
|
||||||
|
+ resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
+ my += HEIGHT(c) + ih;
|
||||||
|
+ } else {
|
||||||
|
+ /* stack clients are stacked vertically */
|
||||||
|
+ if ((i - m->nmaster) % 2 ) {
|
||||||
|
+ resize(c, lx, ly, lw - (2*c->bw), lh * (c->cfact / lfacts) + ((i - 2*m->nmaster) < 2*lrest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
+ ly += HEIGHT(c) + ih;
|
||||||
|
+ } else {
|
||||||
|
+ resize(c, rx, ry, rw - (2*c->bw), rh * (c->cfact / rfacts) + ((i - 2*m->nmaster) < 2*rrest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
+ ry += HEIGHT(c) + ih;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+centeredfloatingmaster(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ unsigned int i, n;
|
||||||
|
+ float mfacts, sfacts;
|
||||||
|
+ float mivf = 1.0; // master inner vertical gap factor
|
||||||
|
+ int oh, ov, ih, iv, mrest, srest;
|
||||||
|
+ int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
+ int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
+ if (n == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ sx = mx = m->wx + ov;
|
||||||
|
+ sy = my = m->wy + oh;
|
||||||
|
+ sh = mh = m->wh - 2*oh;
|
||||||
|
+ mw = m->ww - 2*ov - iv*(n - 1);
|
||||||
|
+ sw = m->ww - 2*ov - iv*(n - m->nmaster - 1);
|
||||||
|
+
|
||||||
|
+ if (m->nmaster && n > m->nmaster) {
|
||||||
|
+ mivf = 0.8;
|
||||||
|
+ /* go mfact box in the center if more than nmaster clients */
|
||||||
|
+ if (m->ww > m->wh) {
|
||||||
|
+ mw = m->ww * m->mfact - iv*mivf*(MIN(n, m->nmaster) - 1);
|
||||||
|
+ mh = m->wh * 0.9;
|
||||||
|
+ } else {
|
||||||
|
+ mw = m->ww * 0.9 - iv*mivf*(MIN(n, m->nmaster) - 1);
|
||||||
|
+ mh = m->wh * m->mfact;
|
||||||
|
+ }
|
||||||
|
+ mx = m->wx + (m->ww - mw) / 2;
|
||||||
|
+ my = m->wy + (m->wh - mh - 2*oh) / 2;
|
||||||
|
+
|
||||||
|
+ sx = m->wx + ov;
|
||||||
|
+ sy = m->wy + oh;
|
||||||
|
+ sh = m->wh - 2*oh;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
|
||||||
|
+
|
||||||
|
+ for (i = 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 */
|
||||||
|
+ resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
|
||||||
|
+ mx += WIDTH(c) + iv*mivf;
|
||||||
|
+ } else {
|
||||||
|
+ /* stack clients are stacked horizontally */
|
||||||
|
+ resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
|
||||||
|
+ sx += WIDTH(c) + iv;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Deck layout + gaps
|
||||||
|
+ * https://dwm.suckless.org/patches/deck/
|
||||||
|
+ */
|
||||||
|
+void
|
||||||
|
+deck(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ unsigned int i, n;
|
||||||
|
+ int oh, ov, ih, iv;
|
||||||
|
+ int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
+ int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
+ float mfacts, sfacts;
|
||||||
|
+ int mrest, srest;
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
+ if (n == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ sx = mx = m->wx + ov;
|
||||||
|
+ sy = my = m->wy + oh;
|
||||||
|
+ sh = mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
|
||||||
|
+ sw = mw = m->ww - 2*ov;
|
||||||
|
+
|
||||||
|
+ if (m->nmaster && n > m->nmaster) {
|
||||||
|
+ sw = (mw - iv) * (1 - m->mfact);
|
||||||
|
+ mw = mw - iv - sw;
|
||||||
|
+ sx = mx + mw + iv;
|
||||||
|
+ sh = m->wh - 2*oh;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
|
||||||
|
+
|
||||||
|
+ if (n - m->nmaster > 0) /* override layout symbol */
|
||||||
|
+ snprintf(m->ltsymbol, sizeof m->ltsymbol, "D %d", n - m->nmaster);
|
||||||
|
+
|
||||||
|
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
|
+ if (i < m->nmaster) {
|
||||||
|
+ resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
+ my += HEIGHT(c) + ih;
|
||||||
|
+ } else {
|
||||||
|
+ resize(c, sx, sy, sw - (2*c->bw), sh - (2*c->bw), 0);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Fibonacci layout + gaps
|
||||||
|
+ * https://dwm.suckless.org/patches/fibonacci/
|
||||||
|
+ */
|
||||||
|
+void
|
||||||
|
+fibonacci(Monitor *m, int s)
|
||||||
|
+{
|
||||||
|
+ unsigned int i, n;
|
||||||
|
+ int nx, ny, nw, nh;
|
||||||
|
+ int oh, ov, ih, iv;
|
||||||
|
+ int nv, hrest = 0, wrest = 0, r = 1;
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
+ if (n == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ nx = m->wx + ov;
|
||||||
|
+ ny = m->wy + oh;
|
||||||
|
+ nw = m->ww - 2*ov;
|
||||||
|
+ nh = m->wh - 2*oh;
|
||||||
|
+
|
||||||
|
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
|
||||||
|
+ if (r) {
|
||||||
|
+ if ((i % 2 && (nh - ih) / 2 <= (bh + 2*c->bw))
|
||||||
|
+ || (!(i % 2) && (nw - iv) / 2 <= (bh + 2*c->bw))) {
|
||||||
|
+ r = 0;
|
||||||
|
+ }
|
||||||
|
+ if (r && i < n - 1) {
|
||||||
|
+ if (i % 2) {
|
||||||
|
+ nv = (nh - ih) / 2;
|
||||||
|
+ hrest = nh - 2*nv - ih;
|
||||||
|
+ nh = nv;
|
||||||
|
+ } else {
|
||||||
|
+ nv = (nw - iv) / 2;
|
||||||
|
+ wrest = nw - 2*nv - iv;
|
||||||
|
+ nw = nv;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((i % 4) == 2 && !s)
|
||||||
|
+ nx += nw + iv;
|
||||||
|
+ else if ((i % 4) == 3 && !s)
|
||||||
|
+ ny += nh + ih;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((i % 4) == 0) {
|
||||||
|
+ if (s) {
|
||||||
|
+ ny += nh + ih;
|
||||||
|
+ nh += hrest;
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ nh -= hrest;
|
||||||
|
+ ny -= nh + ih;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else if ((i % 4) == 1) {
|
||||||
|
+ nx += nw + iv;
|
||||||
|
+ nw += wrest;
|
||||||
|
+ }
|
||||||
|
+ else if ((i % 4) == 2) {
|
||||||
|
+ ny += nh + ih;
|
||||||
|
+ nh += hrest;
|
||||||
|
+ if (i < n - 1)
|
||||||
|
+ nw += wrest;
|
||||||
|
+ }
|
||||||
|
+ else if ((i % 4) == 3) {
|
||||||
|
+ if (s) {
|
||||||
|
+ nx += nw + iv;
|
||||||
|
+ nw -= wrest;
|
||||||
|
+ } else {
|
||||||
|
+ nw -= wrest;
|
||||||
|
+ nx -= nw + iv;
|
||||||
|
+ nh += hrest;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (i == 0) {
|
||||||
|
+ if (n != 1) {
|
||||||
|
+ nw = (m->ww - iv - 2*ov) - (m->ww - iv - 2*ov) * (1 - m->mfact);
|
||||||
|
+ wrest = 0;
|
||||||
|
+ }
|
||||||
|
+ ny = m->wy + oh;
|
||||||
|
+ }
|
||||||
|
+ else if (i == 1)
|
||||||
|
+ nw = m->ww - nw - iv - 2*ov;
|
||||||
|
+ i++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ resize(c, nx, ny, nw - (2*c->bw), nh - (2*c->bw), False);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+dwindle(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ fibonacci(m, 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+spiral(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ fibonacci(m, 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Gappless grid layout + gaps (ironically)
|
||||||
|
+ * https://dwm.suckless.org/patches/gaplessgrid/
|
||||||
|
+ */
|
||||||
|
+void
|
||||||
|
+gaplessgrid(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ unsigned int i, n;
|
||||||
|
+ int x, y, cols, rows, ch, cw, cn, rn, rrest, crest; // counters
|
||||||
|
+ int oh, ov, ih, iv;
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
+ if (n == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /* grid dimensions */
|
||||||
|
+ for (cols = 0; cols <= n/2; cols++)
|
||||||
|
+ if (cols*cols >= n)
|
||||||
|
+ break;
|
||||||
|
+ if (n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */
|
||||||
|
+ cols = 2;
|
||||||
|
+ rows = n/cols;
|
||||||
|
+ cn = rn = 0; // reset column no, row no, client count
|
||||||
|
+
|
||||||
|
+ ch = (m->wh - 2*oh - ih * (rows - 1)) / rows;
|
||||||
|
+ cw = (m->ww - 2*ov - iv * (cols - 1)) / cols;
|
||||||
|
+ rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
|
||||||
|
+ crest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols;
|
||||||
|
+ x = m->wx + ov;
|
||||||
|
+ y = m->wy + oh;
|
||||||
|
+
|
||||||
|
+ for (i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) {
|
||||||
|
+ if (i/rows + 1 > cols - n%cols) {
|
||||||
|
+ rows = n/cols + 1;
|
||||||
|
+ ch = (m->wh - 2*oh - ih * (rows - 1)) / rows;
|
||||||
|
+ rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
|
||||||
|
+ }
|
||||||
|
+ resize(c,
|
||||||
|
+ x,
|
||||||
|
+ y + rn*(ch + ih) + MIN(rn, rrest),
|
||||||
|
+ cw + (cn < crest ? 1 : 0) - 2*c->bw,
|
||||||
|
+ ch + (rn < rrest ? 1 : 0) - 2*c->bw,
|
||||||
|
+ 0);
|
||||||
|
+ rn++;
|
||||||
|
+ if (rn >= rows) {
|
||||||
|
+ rn = 0;
|
||||||
|
+ x += cw + ih + (cn < crest ? 1 : 0);
|
||||||
|
+ cn++;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Gridmode layout + gaps
|
||||||
|
+ * https://dwm.suckless.org/patches/gridmode/
|
||||||
|
+ */
|
||||||
|
+void
|
||||||
|
+grid(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ unsigned int i, n;
|
||||||
|
+ int cx, cy, cw, ch, cc, cr, chrest, cwrest, cols, rows;
|
||||||
|
+ int oh, ov, ih, iv;
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ getgaps(m, &oh, &ov, &ih, &iv, &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 - 2*oh - ih * (rows - 1)) / (rows ? rows : 1);
|
||||||
|
+ cw = (m->ww - 2*ov - iv * (cols - 1)) / (cols ? cols : 1);
|
||||||
|
+ chrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
|
||||||
|
+ cwrest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols;
|
||||||
|
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
|
||||||
|
+ cc = i / rows;
|
||||||
|
+ cr = i % rows;
|
||||||
|
+ cx = m->wx + ov + cc * (cw + iv) + MIN(cc, cwrest);
|
||||||
|
+ cy = m->wy + oh + cr * (ch + ih) + MIN(cr, chrest);
|
||||||
|
+ resize(c, cx, cy, cw + (cc < cwrest ? 1 : 0) - 2*c->bw, ch + (cr < chrest ? 1 : 0) - 2*c->bw, False);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Horizontal grid layout + gaps
|
||||||
|
+ * https://dwm.suckless.org/patches/horizgrid/
|
||||||
|
+ */
|
||||||
|
+void
|
||||||
|
+horizgrid(Monitor *m) {
|
||||||
|
+ Client *c;
|
||||||
|
+ unsigned int n, i;
|
||||||
|
+ int oh, ov, ih, iv;
|
||||||
|
+ int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
+ int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
+ int ntop, nbottom = 1;
|
||||||
|
+ float mfacts = 0, sfacts = 0;
|
||||||
|
+ int mrest, srest, mtotal = 0, stotal = 0;
|
||||||
|
+
|
||||||
|
+ /* Count windows */
|
||||||
|
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
+ if (n == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (n <= 2)
|
||||||
|
+ ntop = n;
|
||||||
|
+ else {
|
||||||
|
+ ntop = n / 2;
|
||||||
|
+ nbottom = n - ntop;
|
||||||
|
+ }
|
||||||
|
+ sx = mx = m->wx + ov;
|
||||||
|
+ sy = my = m->wy + oh;
|
||||||
|
+ sh = mh = m->wh - 2*oh;
|
||||||
|
+ sw = mw = m->ww - 2*ov;
|
||||||
|
+
|
||||||
|
+ if (n > ntop) {
|
||||||
|
+ sh = (mh - ih) / 2;
|
||||||
|
+ mh = mh - ih - sh;
|
||||||
|
+ sy = my + mh + ih;
|
||||||
|
+ mw = m->ww - 2*ov - iv * (ntop - 1);
|
||||||
|
+ sw = m->ww - 2*ov - iv * (nbottom - 1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* calculate facts */
|
||||||
|
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
|
+ if (i < ntop)
|
||||||
|
+ mfacts += c->cfact;
|
||||||
|
+ else
|
||||||
|
+ sfacts += c->cfact;
|
||||||
|
+
|
||||||
|
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
|
+ if (i < ntop)
|
||||||
|
+ mtotal += mh * (c->cfact / mfacts);
|
||||||
|
+ else
|
||||||
|
+ stotal += sw * (c->cfact / sfacts);
|
||||||
|
+
|
||||||
|
+ mrest = mh - mtotal;
|
||||||
|
+ srest = sw - stotal;
|
||||||
|
+
|
||||||
|
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
|
+ if (i < ntop) {
|
||||||
|
+ resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
|
||||||
|
+ mx += WIDTH(c) + iv;
|
||||||
|
+ } else {
|
||||||
|
+ resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - ntop) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
|
||||||
|
+ sx += WIDTH(c) + iv;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * nrowgrid layout + gaps
|
||||||
|
+ * https://dwm.suckless.org/patches/nrowgrid/
|
||||||
|
+ */
|
||||||
|
+void
|
||||||
|
+nrowgrid(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ unsigned int n;
|
||||||
|
+ int ri = 0, ci = 0; /* counters */
|
||||||
|
+ int oh, ov, ih, iv; /* vanitygap settings */
|
||||||
|
+ unsigned int cx, cy, cw, ch; /* client geometry */
|
||||||
|
+ unsigned int uw = 0, uh = 0, uc = 0; /* utilization trackers */
|
||||||
|
+ unsigned int cols, rows = m->nmaster + 1;
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ /* count clients */
|
||||||
|
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
+
|
||||||
|
+ /* nothing to do here */
|
||||||
|
+ if (n == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /* force 2 clients to always split vertically */
|
||||||
|
+ if (FORCE_VSPLIT && n == 2)
|
||||||
|
+ rows = 1;
|
||||||
|
+
|
||||||
|
+ /* never allow empty rows */
|
||||||
|
+ if (n < rows)
|
||||||
|
+ rows = n;
|
||||||
|
+
|
||||||
|
+ /* define first row */
|
||||||
|
+ cols = n / rows;
|
||||||
|
+ uc = cols;
|
||||||
|
+ cy = m->wy + oh;
|
||||||
|
+ ch = (m->wh - 2*oh - ih*(rows - 1)) / rows;
|
||||||
|
+ uh = ch;
|
||||||
|
+
|
||||||
|
+ for (c = nexttiled(m->clients); c; c = nexttiled(c->next), ci++) {
|
||||||
|
+ if (ci == cols) {
|
||||||
|
+ uw = 0;
|
||||||
|
+ ci = 0;
|
||||||
|
+ ri++;
|
||||||
|
+
|
||||||
|
+ /* next row */
|
||||||
|
+ cols = (n - uc) / (rows - ri);
|
||||||
|
+ uc += cols;
|
||||||
|
+ cy = m->wy + oh + uh + ih;
|
||||||
|
+ uh += ch + ih;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ cx = m->wx + ov + uw;
|
||||||
|
+ cw = (m->ww - 2*ov - uw) / (cols - ci);
|
||||||
|
+ uw += cw + iv;
|
||||||
|
+
|
||||||
|
+ resize(c, cx, cy, cw - (2*c->bw), ch - (2*c->bw), 0);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Default tile layout + gaps
|
||||||
|
+ */
|
||||||
|
+static void
|
||||||
|
+tile(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ unsigned int i, n;
|
||||||
|
+ int oh, ov, ih, iv;
|
||||||
|
+ int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
+ int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
+ float mfacts, sfacts;
|
||||||
|
+ int mrest, srest;
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
+ if (n == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ sx = mx = m->wx + ov;
|
||||||
|
+ sy = my = m->wy + oh;
|
||||||
|
+ mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
|
||||||
|
+ sh = m->wh - 2*oh - ih * (n - m->nmaster - 1);
|
||||||
|
+ sw = mw = m->ww - 2*ov;
|
||||||
|
+
|
||||||
|
+ if (m->nmaster && n > m->nmaster) {
|
||||||
|
+ sw = (mw - iv) * (1 - m->mfact);
|
||||||
|
+ mw = mw - iv - sw;
|
||||||
|
+ sx = mx + mw + iv;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
|
||||||
|
+
|
||||||
|
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
|
+ if (i < m->nmaster) {
|
||||||
|
+ resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
+ my += HEIGHT(c) + ih;
|
||||||
|
+ } else {
|
||||||
|
+ resize(c, sx, sy, sw - (2*c->bw), sh * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
+ sy += HEIGHT(c) + ih;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
\ No newline at end of file
|
||||||
|
--
|
||||||
|
2.19.1
|
||||||
|
|
75
patches/dwm-combo-6.1.diff
Normal file
75
patches/dwm-combo-6.1.diff
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 0362114..40b7a99 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -234,6 +234,11 @@ static int xerrordummy(Display *dpy, XErrorEvent *ee);
|
||||||
|
static int xerrorstart(Display *dpy, XErrorEvent *ee);
|
||||||
|
static void zoom(const Arg *arg);
|
||||||
|
|
||||||
|
+static void keyrelease(XEvent *e);
|
||||||
|
+static void combotag(const Arg *arg);
|
||||||
|
+static void comboview(const Arg *arg);
|
||||||
|
+
|
||||||
|
+
|
||||||
|
/* variables */
|
||||||
|
static const char broken[] = "broken";
|
||||||
|
static char stext[256];
|
||||||
|
@@ -244,6 +249,7 @@ static int (*xerrorxlib)(Display *, XErrorEvent *);
|
||||||
|
static unsigned int numlockmask = 0;
|
||||||
|
static void (*handler[LASTEvent]) (XEvent *) = {
|
||||||
|
[ButtonPress] = buttonpress,
|
||||||
|
+ [ButtonRelease] = keyrelease,
|
||||||
|
[ClientMessage] = clientmessage,
|
||||||
|
[ConfigureRequest] = configurerequest,
|
||||||
|
[ConfigureNotify] = configurenotify,
|
||||||
|
@@ -251,6 +257,7 @@ static void (*handler[LASTEvent]) (XEvent *) = {
|
||||||
|
[EnterNotify] = enternotify,
|
||||||
|
[Expose] = expose,
|
||||||
|
[FocusIn] = focusin,
|
||||||
|
+ [KeyRelease] = keyrelease,
|
||||||
|
[KeyPress] = keypress,
|
||||||
|
[MappingNotify] = mappingnotify,
|
||||||
|
[MapRequest] = maprequest,
|
||||||
|
@@ -274,6 +281,42 @@ static Window root;
|
||||||
|
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
|
||||||
|
|
||||||
|
/* function implementations */
|
||||||
|
+static int combo = 0;
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+keyrelease(XEvent *e) {
|
||||||
|
+ combo = 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+combotag(const Arg *arg) {
|
||||||
|
+ if(selmon->sel && arg->ui & TAGMASK) {
|
||||||
|
+ if (combo) {
|
||||||
|
+ selmon->sel->tags |= arg->ui & TAGMASK;
|
||||||
|
+ } else {
|
||||||
|
+ combo = 1;
|
||||||
|
+ selmon->sel->tags = arg->ui & TAGMASK;
|
||||||
|
+ }
|
||||||
|
+ focus(NULL);
|
||||||
|
+ arrange(selmon);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+comboview(const Arg *arg) {
|
||||||
|
+ unsigned newtags = arg->ui & TAGMASK;
|
||||||
|
+ if (combo) {
|
||||||
|
+ selmon->tagset[selmon->seltags] |= newtags;
|
||||||
|
+ } else {
|
||||||
|
+ selmon->seltags ^= 1; /*toggle tagset*/
|
||||||
|
+ combo = 1;
|
||||||
|
+ if (newtags)
|
||||||
|
+ selmon->tagset[selmon->seltags] = newtags;
|
||||||
|
+ }
|
||||||
|
+ focus(NULL);
|
||||||
|
+ arrange(selmon);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
applyrules(Client *c)
|
||||||
|
{
|
116
patches/dwm-cool-autostart-6.2.diff
Normal file
116
patches/dwm-cool-autostart-6.2.diff
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
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)
|
||||||
|
|
93
patches/dwm-cyclelayouts-20180524-6.2.diff
Normal file
93
patches/dwm-cyclelayouts-20180524-6.2.diff
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
From a09e766a4342f580582082a92b2de65f33208eb4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Christopher Drelich <cd@cdrakka.com>
|
||||||
|
Date: Thu, 24 May 2018 00:56:56 -0400
|
||||||
|
Subject: [PATCH] Function to cycle through available layouts.
|
||||||
|
|
||||||
|
MOD-CTRL-, and MOD-CTRL-.
|
||||||
|
cycle backwards and forwards through available layouts.
|
||||||
|
Probably only useful if you have a lot of additional layouts.
|
||||||
|
The NULL, NULL layout should always be the last layout in your list,
|
||||||
|
in order to guarantee consistent behavior.
|
||||||
|
---
|
||||||
|
config.def.h | 3 +++
|
||||||
|
dwm.1 | 6 ++++++
|
||||||
|
dwm.c | 18 ++++++++++++++++++
|
||||||
|
3 files changed, 27 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index a9ac303..153b880 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -41,6 +41,7 @@ static const Layout layouts[] = {
|
||||||
|
{ "[]=", tile }, /* first entry is default */
|
||||||
|
{ "><>", NULL }, /* no layout function means floating behavior */
|
||||||
|
{ "[M]", monocle },
|
||||||
|
+ { NULL, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* key definitions */
|
||||||
|
@@ -76,6 +77,8 @@ static Key keys[] = {
|
||||||
|
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
||||||
|
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
|
||||||
|
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
|
||||||
|
+ { MODKEY|ControlMask, XK_comma, cyclelayout, {.i = -1 } },
|
||||||
|
+ { MODKEY|ControlMask, XK_period, cyclelayout, {.i = +1 } },
|
||||||
|
{ MODKEY, XK_space, setlayout, {0} },
|
||||||
|
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
||||||
|
{ MODKEY, XK_0, view, {.ui = ~0 } },
|
||||||
|
diff --git a/dwm.1 b/dwm.1
|
||||||
|
index 13b3729..165891b 100644
|
||||||
|
--- a/dwm.1
|
||||||
|
+++ b/dwm.1
|
||||||
|
@@ -92,6 +92,12 @@ Sets monocle layout.
|
||||||
|
.B Mod1\-space
|
||||||
|
Toggles between current and previous layout.
|
||||||
|
.TP
|
||||||
|
+.B Mod1\-Control\-,
|
||||||
|
+Cycles backwards in layout list.
|
||||||
|
+.TP
|
||||||
|
+.B Mod1\-Control\-.
|
||||||
|
+Cycles forwards in layout list.
|
||||||
|
+.TP
|
||||||
|
.B Mod1\-j
|
||||||
|
Focus next window.
|
||||||
|
.TP
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index bb95e26..db73000 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -157,6 +157,7 @@ static void configure(Client *c);
|
||||||
|
static void configurenotify(XEvent *e);
|
||||||
|
static void configurerequest(XEvent *e);
|
||||||
|
static Monitor *createmon(void);
|
||||||
|
+static void cyclelayout(const Arg *arg);
|
||||||
|
static void destroynotify(XEvent *e);
|
||||||
|
static void detach(Client *c);
|
||||||
|
static void detachstack(Client *c);
|
||||||
|
@@ -645,6 +646,23 @@ createmon(void)
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
+cyclelayout(const Arg *arg) {
|
||||||
|
+ Layout *l;
|
||||||
|
+ for(l = (Layout *)layouts; l != selmon->lt[selmon->sellt]; l++);
|
||||||
|
+ if(arg->i > 0) {
|
||||||
|
+ if(l->symbol && (l + 1)->symbol)
|
||||||
|
+ setlayout(&((Arg) { .v = (l + 1) }));
|
||||||
|
+ else
|
||||||
|
+ setlayout(&((Arg) { .v = layouts }));
|
||||||
|
+ } else {
|
||||||
|
+ if(l != layouts && (l - 1)->symbol)
|
||||||
|
+ setlayout(&((Arg) { .v = (l - 1) }));
|
||||||
|
+ else
|
||||||
|
+ setlayout(&((Arg) { .v = &layouts[LENGTH(layouts) - 2] }));
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
destroynotify(XEvent *e)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
--
|
||||||
|
2.7.4
|
||||||
|
|
240
patches/dwm-dwmc-6.2.diff
Normal file
240
patches/dwm-dwmc-6.2.diff
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
From d94cb6f1a553d19127f44dbdc96e8bb5041956c2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nihal Jere <noocsharp@gmail.com>
|
||||||
|
Date: Sat, 21 Mar 2020 15:16:49 -0500
|
||||||
|
Subject: [PATCH] dwm-client
|
||||||
|
|
||||||
|
---
|
||||||
|
Makefile | 2 +-
|
||||||
|
config.def.h | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
dwm.c | 55 +++++++++++++++++++++++++++++++++++++++--
|
||||||
|
dwmc | 40 ++++++++++++++++++++++++++++++
|
||||||
|
4 files changed, 164 insertions(+), 3 deletions(-)
|
||||||
|
create mode 100755 dwmc
|
||||||
|
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index 77bcbc0..f837f5c 100644
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -38,7 +38,7 @@ dist: clean
|
||||||
|
|
||||||
|
install: all
|
||||||
|
mkdir -p ${DESTDIR}${PREFIX}/bin
|
||||||
|
- cp -f dwm ${DESTDIR}${PREFIX}/bin
|
||||||
|
+ cp -f dwm dwmc ${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
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 1c0b587..efbae79 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -113,3 +113,73 @@ static Button buttons[] = {
|
||||||
|
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
|
||||||
|
};
|
||||||
|
|
||||||
|
+void
|
||||||
|
+setlayoutex(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ setlayout(&((Arg) { .v = &layouts[arg->i] }));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+viewex(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ view(&((Arg) { .ui = 1 << arg->ui }));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+viewall(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ view(&((Arg){.ui = ~0}));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+toggleviewex(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ toggleview(&((Arg) { .ui = 1 << arg->ui }));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+tagex(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ tag(&((Arg) { .ui = 1 << arg->ui }));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+toggletagex(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ toggletag(&((Arg) { .ui = 1 << arg->ui }));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+tagall(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ tag(&((Arg){.ui = ~0}));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* signal definitions */
|
||||||
|
+/* signum must be greater than 0 */
|
||||||
|
+/* trigger signals using `xsetroot -name "fsignal:<signame> [<type> <value>]"` */
|
||||||
|
+static Signal signals[] = {
|
||||||
|
+ /* signum function */
|
||||||
|
+ { "focusstack", focusstack },
|
||||||
|
+ { "setmfact", setmfact },
|
||||||
|
+ { "togglebar", togglebar },
|
||||||
|
+ { "incnmaster", incnmaster },
|
||||||
|
+ { "togglefloating", togglefloating },
|
||||||
|
+ { "focusmon", focusmon },
|
||||||
|
+ { "tagmon", tagmon },
|
||||||
|
+ { "zoom", zoom },
|
||||||
|
+ { "view", view },
|
||||||
|
+ { "viewall", viewall },
|
||||||
|
+ { "viewex", viewex },
|
||||||
|
+ { "toggleview", view },
|
||||||
|
+ { "toggleviewex", toggleviewex },
|
||||||
|
+ { "tag", tag },
|
||||||
|
+ { "tagall", tagall },
|
||||||
|
+ { "tagex", tagex },
|
||||||
|
+ { "toggletag", tag },
|
||||||
|
+ { "toggletagex", toggletagex },
|
||||||
|
+ { "killclient", killclient },
|
||||||
|
+ { "quit", quit },
|
||||||
|
+ { "setlayout", setlayout },
|
||||||
|
+ { "setlayoutex", setlayoutex },
|
||||||
|
+};
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 4465af1..aa53706 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -106,6 +106,11 @@ typedef struct {
|
||||||
|
const Arg arg;
|
||||||
|
} Key;
|
||||||
|
|
||||||
|
+typedef struct {
|
||||||
|
+ const char * sig;
|
||||||
|
+ void (*func)(const Arg *);
|
||||||
|
+} Signal;
|
||||||
|
+
|
||||||
|
typedef struct {
|
||||||
|
const char *symbol;
|
||||||
|
void (*arrange)(Monitor *);
|
||||||
|
@@ -148,6 +153,7 @@ static void arrange(Monitor *m);
|
||||||
|
static void arrangemon(Monitor *m);
|
||||||
|
static void attach(Client *c);
|
||||||
|
static void attachstack(Client *c);
|
||||||
|
+static int fake_signal(void);
|
||||||
|
static void buttonpress(XEvent *e);
|
||||||
|
static void checkotherwm(void);
|
||||||
|
static void cleanup(void);
|
||||||
|
@@ -998,6 +1004,49 @@ keypress(XEvent *e)
|
||||||
|
keys[i].func(&(keys[i].arg));
|
||||||
|
}
|
||||||
|
|
||||||
|
+int
|
||||||
|
+fake_signal(void)
|
||||||
|
+{
|
||||||
|
+ char fsignal[256];
|
||||||
|
+ char indicator[9] = "fsignal:";
|
||||||
|
+ char str_sig[50];
|
||||||
|
+ char param[16];
|
||||||
|
+ int i, len_str_sig, n, paramn;
|
||||||
|
+ size_t len_fsignal, len_indicator = strlen(indicator);
|
||||||
|
+ Arg arg;
|
||||||
|
+
|
||||||
|
+ // Get root name property
|
||||||
|
+ if (gettextprop(root, XA_WM_NAME, fsignal, sizeof(fsignal))) {
|
||||||
|
+ len_fsignal = strlen(fsignal);
|
||||||
|
+
|
||||||
|
+ // Check if this is indeed a fake signal
|
||||||
|
+ if (len_indicator > len_fsignal ? 0 : strncmp(indicator, fsignal, len_indicator) == 0) {
|
||||||
|
+ paramn = sscanf(fsignal+len_indicator, "%s%n%s%n", str_sig, &len_str_sig, param, &n);
|
||||||
|
+
|
||||||
|
+ if (paramn == 1) arg = (Arg) {0};
|
||||||
|
+ else if (paramn > 2) return 1;
|
||||||
|
+ else if (strncmp(param, "i", n - len_str_sig) == 0)
|
||||||
|
+ sscanf(fsignal + len_indicator + n, "%i", &(arg.i));
|
||||||
|
+ else if (strncmp(param, "ui", n - len_str_sig) == 0)
|
||||||
|
+ sscanf(fsignal + len_indicator + n, "%u", &(arg.ui));
|
||||||
|
+ else if (strncmp(param, "f", n - len_str_sig) == 0)
|
||||||
|
+ sscanf(fsignal + len_indicator + n, "%f", &(arg.f));
|
||||||
|
+ else return 1;
|
||||||
|
+
|
||||||
|
+ // Check if a signal was found, and if so handle it
|
||||||
|
+ for (i = 0; i < LENGTH(signals); i++)
|
||||||
|
+ if (strncmp(str_sig, signals[i].sig, len_str_sig) == 0 && signals[i].func)
|
||||||
|
+ signals[i].func(&(arg));
|
||||||
|
+
|
||||||
|
+ // A fake signal was sent
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // No fake signal was sent, so proceed with update
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
killclient(const Arg *arg)
|
||||||
|
{
|
||||||
|
@@ -1215,8 +1264,10 @@ propertynotify(XEvent *e)
|
||||||
|
Window trans;
|
||||||
|
XPropertyEvent *ev = &e->xproperty;
|
||||||
|
|
||||||
|
- if ((ev->window == root) && (ev->atom == XA_WM_NAME))
|
||||||
|
- updatestatus();
|
||||||
|
+ if ((ev->window == root) && (ev->atom == XA_WM_NAME)) {
|
||||||
|
+ if (!fake_signal())
|
||||||
|
+ updatestatus();
|
||||||
|
+ }
|
||||||
|
else if (ev->state == PropertyDelete)
|
||||||
|
return; /* ignore */
|
||||||
|
else if ((c = wintoclient(ev->window))) {
|
||||||
|
diff --git a/dwmc b/dwmc
|
||||||
|
new file mode 100755
|
||||||
|
index 0000000..5ff8dbc
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/dwmc
|
||||||
|
@@ -0,0 +1,40 @@
|
||||||
|
+#!/usr/bin/env sh
|
||||||
|
+
|
||||||
|
+signal() {
|
||||||
|
+ xsetroot -name "fsignal:$*"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+case $# in
|
||||||
|
+1)
|
||||||
|
+ case $1 in
|
||||||
|
+ setlayout | view | viewall | togglebar | togglefloating | zoom | killclient | quit)
|
||||||
|
+ signal $1
|
||||||
|
+ ;;
|
||||||
|
+ *)
|
||||||
|
+ echo "Unknown command or missing one argument."
|
||||||
|
+ exit 1
|
||||||
|
+ ;;
|
||||||
|
+ esac
|
||||||
|
+ ;;
|
||||||
|
+2)
|
||||||
|
+ case $1 in
|
||||||
|
+ view)
|
||||||
|
+ signal $1 ui $2
|
||||||
|
+ ;;
|
||||||
|
+ viewex | toggleviewex | tagex | toggletagex | setlayoutex | focusstack | incnmaster | focusmon | tagmon)
|
||||||
|
+ signal $1 i $2
|
||||||
|
+ ;;
|
||||||
|
+ setmfact)
|
||||||
|
+ signal $1 f $2
|
||||||
|
+ ;;
|
||||||
|
+ *)
|
||||||
|
+ echo "Unknown command or one too many arguments."
|
||||||
|
+ exit 1
|
||||||
|
+ ;;
|
||||||
|
+ esac
|
||||||
|
+ ;;
|
||||||
|
+*)
|
||||||
|
+ echo "Too many arguments."
|
||||||
|
+ exit 1
|
||||||
|
+ ;;
|
||||||
|
+esac
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
27
patches/dwm-fixborders-6.2.diff
Normal file
27
patches/dwm-fixborders-6.2.diff
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From 1529909466206016f2101457bbf37c67195714c8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jakub Leszczak <szatan@gecc.xyz>
|
||||||
|
Date: Fri, 22 Nov 2019 10:46:53 +0800
|
||||||
|
Subject: [PATCH] Fix transparent borders
|
||||||
|
|
||||||
|
When terminal has transparency then its borders also become transparent.
|
||||||
|
Fix it by removing transparency from any pixels drawn.
|
||||||
|
---
|
||||||
|
drw.c | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/drw.c b/drw.c
|
||||||
|
index 8fd1ca4..490a592 100644
|
||||||
|
--- a/drw.c
|
||||||
|
+++ b/drw.c
|
||||||
|
@@ -202,6 +202,8 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
|
||||||
|
DefaultColormap(drw->dpy, drw->screen),
|
||||||
|
clrname, dest))
|
||||||
|
die("error, cannot allocate color '%s'", clrname);
|
||||||
|
+
|
||||||
|
+ dest->pixel |= 0xff << 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wrapper to create color schemes. The caller has to call free(3) on the
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
3246
patches/dwm-ipc-20201106-f04cac6.diff
Normal file
3246
patches/dwm-ipc-20201106-f04cac6.diff
Normal file
File diff suppressed because it is too large
Load Diff
73
patches/dwm-movestack-6.1.diff
Normal file
73
patches/dwm-movestack-6.1.diff
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
diff -r 050d521d66d8 config.def.h
|
||||||
|
--- a/config.def.h Tue Aug 24 13:13:20 2010 +0100
|
||||||
|
+++ b/config.def.h Sun Sep 05 18:43:07 2010 +0200
|
||||||
|
@@ -57,6 +57,7 @@
|
||||||
|
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL };
|
||||||
|
static const char *termcmd[] = { "st", NULL };
|
||||||
|
|
||||||
|
+#include "movestack.c"
|
||||||
|
static Key keys[] = {
|
||||||
|
/* modifier key function argument */
|
||||||
|
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
|
||||||
|
@@ -68,6 +69,8 @@
|
||||||
|
{ 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 -r 050d521d66d8 movestack.c
|
||||||
|
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
|
||||||
|
+++ b/movestack.c Sun Sep 05 18:43:07 2010 +0200
|
||||||
|
@@ -0,0 +1,49 @@
|
||||||
|
+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);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
31
patches/dwm-noborderfloatingfix-6.2.diff
Normal file
31
patches/dwm-noborderfloatingfix-6.2.diff
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
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
|
||||||
|
|
412
patches/dwm-swallow-20200807-b2de9b0.diff
Normal file
412
patches/dwm-swallow-20200807-b2de9b0.diff
Normal file
@ -0,0 +1,412 @@
|
|||||||
|
From b2de9b0fd7988241db516a8f032f26cb9cf32be1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ben <ben@0x1bi.net>
|
||||||
|
Date: Fri, 7 Aug 2020 20:14:29 -0400
|
||||||
|
Subject: [PATCH] added openbsd support for swallowing
|
||||||
|
|
||||||
|
---
|
||||||
|
config.def.h | 9 +-
|
||||||
|
config.mk | 3 +-
|
||||||
|
dwm.c | 235 +++++++++++++++++++++++++++++++++++++++++++++++++--
|
||||||
|
3 files changed, 237 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 1c0b587..fe51476 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -3,6 +3,7 @@
|
||||||
|
/* appearance */
|
||||||
|
static const unsigned int borderpx = 1; /* border pixel of windows */
|
||||||
|
static const unsigned int snap = 32; /* snap pixel */
|
||||||
|
+static const int swallowfloating = 0; /* 1 means swallow floating windows by default */
|
||||||
|
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" };
|
||||||
|
@@ -26,9 +27,11 @@ static const Rule rules[] = {
|
||||||
|
* WM_CLASS(STRING) = instance, class
|
||||||
|
* WM_NAME(STRING) = title
|
||||||
|
*/
|
||||||
|
- /* class instance title tags mask isfloating monitor */
|
||||||
|
- { "Gimp", NULL, NULL, 0, 1, -1 },
|
||||||
|
- { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
|
||||||
|
+ /* class instance title tags mask isfloating isterminal noswallow monitor */
|
||||||
|
+ { "Gimp", NULL, NULL, 0, 1, 0, 0, -1 },
|
||||||
|
+ { "Firefox", NULL, NULL, 1 << 8, 0, 0, -1, -1 },
|
||||||
|
+ { "St", NULL, NULL, 0, 0, 1, 0, -1 },
|
||||||
|
+ { NULL, NULL, "Event Tester", 0, 0, 0, 1, -1 }, /* xev */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* layout(s) */
|
||||||
|
diff --git a/config.mk b/config.mk
|
||||||
|
index 7084c33..ff9e508 100644
|
||||||
|
--- a/config.mk
|
||||||
|
+++ b/config.mk
|
||||||
|
@@ -19,10 +19,11 @@ FREETYPELIBS = -lfontconfig -lXft
|
||||||
|
FREETYPEINC = /usr/include/freetype2
|
||||||
|
# OpenBSD (uncomment)
|
||||||
|
#FREETYPEINC = ${X11INC}/freetype2
|
||||||
|
+#KVMLIB = -lkvm
|
||||||
|
|
||||||
|
# includes and libs
|
||||||
|
INCS = -I${X11INC} -I${FREETYPEINC}
|
||||||
|
-LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
|
||||||
|
+LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lX11-xcb -lxcb -lxcb-res ${KVMLIB}
|
||||||
|
|
||||||
|
# flags
|
||||||
|
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 9fd0286..e9f08f7 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -40,6 +40,12 @@
|
||||||
|
#include <X11/extensions/Xinerama.h>
|
||||||
|
#endif /* XINERAMA */
|
||||||
|
#include <X11/Xft/Xft.h>
|
||||||
|
+#include <X11/Xlib-xcb.h>
|
||||||
|
+#include <xcb/res.h>
|
||||||
|
+#ifdef __OpenBSD__
|
||||||
|
+#include <sys/sysctl.h>
|
||||||
|
+#include <kvm.h>
|
||||||
|
+#endif /* __OpenBSD */
|
||||||
|
|
||||||
|
#include "drw.h"
|
||||||
|
#include "util.h"
|
||||||
|
@@ -92,9 +98,11 @@ 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, isterminal, noswallow;
|
||||||
|
+ pid_t pid;
|
||||||
|
Client *next;
|
||||||
|
Client *snext;
|
||||||
|
+ Client *swallowing;
|
||||||
|
Monitor *mon;
|
||||||
|
Window win;
|
||||||
|
};
|
||||||
|
@@ -138,6 +146,8 @@ typedef struct {
|
||||||
|
const char *title;
|
||||||
|
unsigned int tags;
|
||||||
|
int isfloating;
|
||||||
|
+ int isterminal;
|
||||||
|
+ int noswallow;
|
||||||
|
int monitor;
|
||||||
|
} Rule;
|
||||||
|
|
||||||
|
@@ -235,6 +245,12 @@ static int xerrordummy(Display *dpy, XErrorEvent *ee);
|
||||||
|
static int xerrorstart(Display *dpy, XErrorEvent *ee);
|
||||||
|
static void zoom(const Arg *arg);
|
||||||
|
|
||||||
|
+static pid_t getparentprocess(pid_t p);
|
||||||
|
+static int isdescprocess(pid_t p, pid_t c);
|
||||||
|
+static Client *swallowingclient(Window w);
|
||||||
|
+static Client *termforwin(const Client *c);
|
||||||
|
+static pid_t winpid(Window w);
|
||||||
|
+
|
||||||
|
/* variables */
|
||||||
|
static const char broken[] = "broken";
|
||||||
|
static char stext[256];
|
||||||
|
@@ -269,6 +285,8 @@ static Drw *drw;
|
||||||
|
static Monitor *mons, *selmon;
|
||||||
|
static Window root, wmcheckwin;
|
||||||
|
|
||||||
|
+static xcb_connection_t *xcon;
|
||||||
|
+
|
||||||
|
/* configuration, allows nested code to access above variables */
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
@@ -298,6 +316,8 @@ applyrules(Client *c)
|
||||||
|
&& (!r->class || strstr(class, r->class))
|
||||||
|
&& (!r->instance || strstr(instance, r->instance)))
|
||||||
|
{
|
||||||
|
+ c->isterminal = r->isterminal;
|
||||||
|
+ c->noswallow = r->noswallow;
|
||||||
|
c->isfloating = r->isfloating;
|
||||||
|
c->tags |= r->tags;
|
||||||
|
for (m = mons; m && m->num != r->monitor; m = m->next);
|
||||||
|
@@ -414,6 +434,53 @@ attachstack(Client *c)
|
||||||
|
c->mon->stack = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+swallow(Client *p, Client *c)
|
||||||
|
+{
|
||||||
|
+
|
||||||
|
+ if (c->noswallow || c->isterminal)
|
||||||
|
+ return;
|
||||||
|
+ if (c->noswallow && !swallowfloating && c->isfloating)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ detach(c);
|
||||||
|
+ detachstack(c);
|
||||||
|
+
|
||||||
|
+ setclientstate(c, WithdrawnState);
|
||||||
|
+ XUnmapWindow(dpy, p->win);
|
||||||
|
+
|
||||||
|
+ p->swallowing = c;
|
||||||
|
+ c->mon = p->mon;
|
||||||
|
+
|
||||||
|
+ Window w = p->win;
|
||||||
|
+ p->win = c->win;
|
||||||
|
+ c->win = w;
|
||||||
|
+ updatetitle(p);
|
||||||
|
+ XMoveResizeWindow(dpy, p->win, p->x, p->y, p->w, p->h);
|
||||||
|
+ arrange(p->mon);
|
||||||
|
+ configure(p);
|
||||||
|
+ updateclientlist();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+unswallow(Client *c)
|
||||||
|
+{
|
||||||
|
+ c->win = c->swallowing->win;
|
||||||
|
+
|
||||||
|
+ free(c->swallowing);
|
||||||
|
+ c->swallowing = NULL;
|
||||||
|
+
|
||||||
|
+ /* unfullscreen the client */
|
||||||
|
+ setfullscreen(c, 0);
|
||||||
|
+ updatetitle(c);
|
||||||
|
+ arrange(c->mon);
|
||||||
|
+ XMapWindow(dpy, c->win);
|
||||||
|
+ XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
|
||||||
|
+ setclientstate(c, NormalState);
|
||||||
|
+ focus(NULL);
|
||||||
|
+ arrange(c->mon);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
buttonpress(XEvent *e)
|
||||||
|
{
|
||||||
|
@@ -653,6 +720,9 @@ destroynotify(XEvent *e)
|
||||||
|
|
||||||
|
if ((c = wintoclient(ev->window)))
|
||||||
|
unmanage(c, 1);
|
||||||
|
+
|
||||||
|
+ else if ((c = swallowingclient(ev->window)))
|
||||||
|
+ unmanage(c->swallowing, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
@@ -1018,12 +1088,13 @@ killclient(const Arg *arg)
|
||||||
|
void
|
||||||
|
manage(Window w, XWindowAttributes *wa)
|
||||||
|
{
|
||||||
|
- Client *c, *t = NULL;
|
||||||
|
+ Client *c, *t = NULL, *term = NULL;
|
||||||
|
Window trans = None;
|
||||||
|
XWindowChanges wc;
|
||||||
|
|
||||||
|
c = ecalloc(1, sizeof(Client));
|
||||||
|
c->win = w;
|
||||||
|
+ c->pid = winpid(w);
|
||||||
|
/* geometry */
|
||||||
|
c->x = c->oldx = wa->x;
|
||||||
|
c->y = c->oldy = wa->y;
|
||||||
|
@@ -1038,6 +1109,7 @@ manage(Window w, XWindowAttributes *wa)
|
||||||
|
} else {
|
||||||
|
c->mon = selmon;
|
||||||
|
applyrules(c);
|
||||||
|
+ term = termforwin(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw)
|
||||||
|
@@ -1074,6 +1146,8 @@ manage(Window w, XWindowAttributes *wa)
|
||||||
|
c->mon->sel = c;
|
||||||
|
arrange(c->mon);
|
||||||
|
XMapWindow(dpy, c->win);
|
||||||
|
+ if (term)
|
||||||
|
+ swallow(term, c);
|
||||||
|
focus(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1768,6 +1842,20 @@ unmanage(Client *c, int destroyed)
|
||||||
|
Monitor *m = c->mon;
|
||||||
|
XWindowChanges wc;
|
||||||
|
|
||||||
|
+ if (c->swallowing) {
|
||||||
|
+ unswallow(c);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ Client *s = swallowingclient(c->win);
|
||||||
|
+ if (s) {
|
||||||
|
+ free(s->swallowing);
|
||||||
|
+ s->swallowing = NULL;
|
||||||
|
+ arrange(m);
|
||||||
|
+ focus(NULL);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
detach(c);
|
||||||
|
detachstack(c);
|
||||||
|
if (!destroyed) {
|
||||||
|
@@ -1782,9 +1870,12 @@ unmanage(Client *c, int destroyed)
|
||||||
|
XUngrabServer(dpy);
|
||||||
|
}
|
||||||
|
free(c);
|
||||||
|
- focus(NULL);
|
||||||
|
- updateclientlist();
|
||||||
|
- arrange(m);
|
||||||
|
+
|
||||||
|
+ if (!s) {
|
||||||
|
+ arrange(m);
|
||||||
|
+ focus(NULL);
|
||||||
|
+ updateclientlist();
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
@@ -2047,6 +2138,136 @@ view(const Arg *arg)
|
||||||
|
arrange(selmon);
|
||||||
|
}
|
||||||
|
|
||||||
|
+pid_t
|
||||||
|
+winpid(Window w)
|
||||||
|
+{
|
||||||
|
+
|
||||||
|
+ pid_t result = 0;
|
||||||
|
+
|
||||||
|
+ #ifdef __linux__
|
||||||
|
+ xcb_res_client_id_spec_t spec = {0};
|
||||||
|
+ spec.client = w;
|
||||||
|
+ spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID;
|
||||||
|
+
|
||||||
|
+ xcb_generic_error_t *e = NULL;
|
||||||
|
+ xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(xcon, 1, &spec);
|
||||||
|
+ xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_reply(xcon, c, &e);
|
||||||
|
+
|
||||||
|
+ if (!r)
|
||||||
|
+ return (pid_t)0;
|
||||||
|
+
|
||||||
|
+ xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids_ids_iterator(r);
|
||||||
|
+ for (; i.rem; xcb_res_client_id_value_next(&i)) {
|
||||||
|
+ spec = i.data->spec;
|
||||||
|
+ if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) {
|
||||||
|
+ uint32_t *t = xcb_res_client_id_value_value(i.data);
|
||||||
|
+ result = *t;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ free(r);
|
||||||
|
+
|
||||||
|
+ if (result == (pid_t)-1)
|
||||||
|
+ result = 0;
|
||||||
|
+
|
||||||
|
+ #endif /* __linux__ */
|
||||||
|
+
|
||||||
|
+ #ifdef __OpenBSD__
|
||||||
|
+ Atom type;
|
||||||
|
+ int format;
|
||||||
|
+ unsigned long len, bytes;
|
||||||
|
+ unsigned char *prop;
|
||||||
|
+ pid_t ret;
|
||||||
|
+
|
||||||
|
+ if (XGetWindowProperty(dpy, w, XInternAtom(dpy, "_NET_WM_PID", 1), 0, 1, False, AnyPropertyType, &type, &format, &len, &bytes, &prop) != Success || !prop)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ ret = *(pid_t*)prop;
|
||||||
|
+ XFree(prop);
|
||||||
|
+ result = ret;
|
||||||
|
+
|
||||||
|
+ #endif /* __OpenBSD__ */
|
||||||
|
+ return result;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+pid_t
|
||||||
|
+getparentprocess(pid_t p)
|
||||||
|
+{
|
||||||
|
+ unsigned int v = 0;
|
||||||
|
+
|
||||||
|
+#ifdef __linux__
|
||||||
|
+ FILE *f;
|
||||||
|
+ char buf[256];
|
||||||
|
+ snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p);
|
||||||
|
+
|
||||||
|
+ if (!(f = fopen(buf, "r")))
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ fscanf(f, "%*u %*s %*c %u", &v);
|
||||||
|
+ fclose(f);
|
||||||
|
+#endif /* __linux__*/
|
||||||
|
+
|
||||||
|
+#ifdef __OpenBSD__
|
||||||
|
+ int n;
|
||||||
|
+ kvm_t *kd;
|
||||||
|
+ struct kinfo_proc *kp;
|
||||||
|
+
|
||||||
|
+ kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, NULL);
|
||||||
|
+ if (!kd)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ kp = kvm_getprocs(kd, KERN_PROC_PID, p, sizeof(*kp), &n);
|
||||||
|
+ v = kp->p_ppid;
|
||||||
|
+#endif /* __OpenBSD__ */
|
||||||
|
+
|
||||||
|
+ return (pid_t)v;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+isdescprocess(pid_t p, pid_t c)
|
||||||
|
+{
|
||||||
|
+ while (p != c && c != 0)
|
||||||
|
+ c = getparentprocess(c);
|
||||||
|
+
|
||||||
|
+ return (int)c;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+Client *
|
||||||
|
+termforwin(const Client *w)
|
||||||
|
+{
|
||||||
|
+ Client *c;
|
||||||
|
+ Monitor *m;
|
||||||
|
+
|
||||||
|
+ if (!w->pid || w->isterminal)
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ for (m = mons; m; m = m->next) {
|
||||||
|
+ for (c = m->clients; c; c = c->next) {
|
||||||
|
+ if (c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid))
|
||||||
|
+ return c;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+Client *
|
||||||
|
+swallowingclient(Window w)
|
||||||
|
+{
|
||||||
|
+ Client *c;
|
||||||
|
+ Monitor *m;
|
||||||
|
+
|
||||||
|
+ for (m = mons; m; m = m->next) {
|
||||||
|
+ for (c = m->clients; c; c = c->next) {
|
||||||
|
+ if (c->swallowing && c->swallowing->win == w)
|
||||||
|
+ return c;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
Client *
|
||||||
|
wintoclient(Window w)
|
||||||
|
{
|
||||||
|
@@ -2138,10 +2359,12 @@ main(int argc, char *argv[])
|
||||||
|
fputs("warning: no locale support\n", stderr);
|
||||||
|
if (!(dpy = XOpenDisplay(NULL)))
|
||||||
|
die("dwm: cannot open display");
|
||||||
|
+ if (!(xcon = XGetXCBConnection(dpy)))
|
||||||
|
+ die("dwm: cannot get xcb connection\n");
|
||||||
|
checkotherwm();
|
||||||
|
setup();
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
- if (pledge("stdio rpath proc exec", NULL) == -1)
|
||||||
|
+ if (pledge("stdio rpath proc exec ps", NULL) == -1)
|
||||||
|
die("pledge");
|
||||||
|
#endif /* __OpenBSD__ */
|
||||||
|
scan();
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
38
patches/dwm-unfloatvisible-6.2.diff
Normal file
38
patches/dwm-unfloatvisible-6.2.diff
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
From a972569532c9d46f79776b0f687ebbbd67a6b69f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alexander Courtis <alex@courtis.org>
|
||||||
|
Date: Mon, 22 Apr 2019 22:23:12 +1000
|
||||||
|
Subject: [PATCH] unfloat any visible windows which have isfloating set
|
||||||
|
|
||||||
|
optionally takes a layout to also apply
|
||||||
|
|
||||||
|
e.g.
|
||||||
|
{ MODKEY|ShiftMask, XK_space, unfloatvisible, {0} },
|
||||||
|
{ MODKEY|ShiftMask, XK_t, unfloatvisible, {.v = &layouts[1]} },
|
||||||
|
---
|
||||||
|
unfloat.c | 14 ++++++++++++++
|
||||||
|
1 file changed, 14 insertions(+)
|
||||||
|
create mode 100644 unfloat.c
|
||||||
|
|
||||||
|
diff --git a/unfloat.c b/unfloat.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..ef84111
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/unfloat.c
|
||||||
|
@@ -0,0 +1,14 @@
|
||||||
|
+void
|
||||||
|
+unfloatvisible(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ for (c = selmon->clients; c; c = c->next)
|
||||||
|
+ if (ISVISIBLE(c) && c->isfloating)
|
||||||
|
+ c->isfloating = c->isfixed;
|
||||||
|
+
|
||||||
|
+ if (arg && arg->v)
|
||||||
|
+ setlayout(arg);
|
||||||
|
+ else
|
||||||
|
+ arrange(selmon);
|
||||||
|
+}
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
235
patches/dwm-xresources-6.2.diff
Normal file
235
patches/dwm-xresources-6.2.diff
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
From 2832bd78a690606a48a7e1d370cd60fd92ee4988 Mon Sep 17 00:00:00 2001
|
||||||
|
From: MLquest8 <miskuzius@gmail.com>
|
||||||
|
Date: Fri, 12 Jun 2020 15:43:31 +0400
|
||||||
|
Subject: [PATCH] handle various setting of various types from Xresources
|
||||||
|
|
||||||
|
---
|
||||||
|
config.def.h | 54 ++++++++++++++++++++++++++-------------
|
||||||
|
drw.c | 2 +-
|
||||||
|
drw.h | 2 +-
|
||||||
|
dwm.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
4 files changed, 111 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 1c0b587..e69f288 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -1,21 +1,22 @@
|
||||||
|
/* See LICENSE file for copyright and license details. */
|
||||||
|
|
||||||
|
/* 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 unsigned int borderpx = 1; /* border pixel of windows */
|
||||||
|
+static unsigned int snap = 32; /* snap pixel */
|
||||||
|
+static int showbar = 1; /* 0 means no bar */
|
||||||
|
+static int topbar = 1; /* 0 means bottom bar */
|
||||||
|
static const char *fonts[] = { "monospace:size=10" };
|
||||||
|
static const char dmenufont[] = "monospace:size=10";
|
||||||
|
-static const char col_gray1[] = "#222222";
|
||||||
|
-static const char col_gray2[] = "#444444";
|
||||||
|
-static const char col_gray3[] = "#bbbbbb";
|
||||||
|
-static const char col_gray4[] = "#eeeeee";
|
||||||
|
-static const char col_cyan[] = "#005577";
|
||||||
|
-static const char *colors[][3] = {
|
||||||
|
- /* fg bg border */
|
||||||
|
- [SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
|
||||||
|
- [SchemeSel] = { col_gray4, col_cyan, col_cyan },
|
||||||
|
+static char normbgcolor[] = "#222222";
|
||||||
|
+static char normbordercolor[] = "#444444";
|
||||||
|
+static char normfgcolor[] = "#bbbbbb";
|
||||||
|
+static char selfgcolor[] = "#eeeeee";
|
||||||
|
+static char selbordercolor[] = "#005577";
|
||||||
|
+static char selbgcolor[] = "#005577";
|
||||||
|
+static char *colors[][3] = {
|
||||||
|
+ /* fg bg border */
|
||||||
|
+ [SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor },
|
||||||
|
+ [SchemeSel] = { selfgcolor, selbgcolor, selbordercolor },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* tagging */
|
||||||
|
@@ -32,9 +33,9 @@ static const Rule rules[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 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 float mfact = 0.55; /* factor of master area size [0.05..0.95] */
|
||||||
|
+static int nmaster = 1; /* number of clients in master area */
|
||||||
|
+static int resizehints = 1; /* 1 means respect size hints in tiled resizals */
|
||||||
|
|
||||||
|
static const Layout layouts[] = {
|
||||||
|
/* symbol arrange function */
|
||||||
|
@@ -56,9 +57,28 @@ static const Layout layouts[] = {
|
||||||
|
|
||||||
|
/* commands */
|
||||||
|
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
|
||||||
|
-static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
|
||||||
|
+static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbordercolor, "-sf", selfgcolor, NULL };
|
||||||
|
static const char *termcmd[] = { "st", NULL };
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Xresources preferences to load at startup
|
||||||
|
+ */
|
||||||
|
+ResourcePref resources[] = {
|
||||||
|
+ { "normbgcolor", STRING, &normbgcolor },
|
||||||
|
+ { "normbordercolor", STRING, &normbordercolor },
|
||||||
|
+ { "normfgcolor", STRING, &normfgcolor },
|
||||||
|
+ { "selbgcolor", STRING, &selbgcolor },
|
||||||
|
+ { "selbordercolor", STRING, &selbordercolor },
|
||||||
|
+ { "selfgcolor", STRING, &selfgcolor },
|
||||||
|
+ { "borderpx", INTEGER, &borderpx },
|
||||||
|
+ { "snap", INTEGER, &snap },
|
||||||
|
+ { "showbar", INTEGER, &showbar },
|
||||||
|
+ { "topbar", INTEGER, &topbar },
|
||||||
|
+ { "nmaster", INTEGER, &nmaster },
|
||||||
|
+ { "resizehints", INTEGER, &resizehints },
|
||||||
|
+ { "mfact", FLOAT, &mfact },
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
static Key keys[] = {
|
||||||
|
/* modifier key function argument */
|
||||||
|
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
|
||||||
|
diff --git a/drw.c b/drw.c
|
||||||
|
index 4cdbcbe..8f1059e 100644
|
||||||
|
--- a/drw.c
|
||||||
|
+++ b/drw.c
|
||||||
|
@@ -208,7 +208,7 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
|
||||||
|
/* Wrapper to create color schemes. The caller has to call free(3) on the
|
||||||
|
* returned color scheme when done using it. */
|
||||||
|
Clr *
|
||||||
|
-drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
|
||||||
|
+drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
Clr *ret;
|
||||||
|
diff --git a/drw.h b/drw.h
|
||||||
|
index 4bcd5ad..42b04ce 100644
|
||||||
|
--- a/drw.h
|
||||||
|
+++ b/drw.h
|
||||||
|
@@ -39,7 +39,7 @@ void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned in
|
||||||
|
|
||||||
|
/* Colorscheme abstraction */
|
||||||
|
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
|
||||||
|
-Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
|
||||||
|
+Clr *drw_scm_create(Drw *drw, char *clrnames[], size_t clrcount);
|
||||||
|
|
||||||
|
/* Cursor abstraction */
|
||||||
|
Cur *drw_cur_create(Drw *drw, int shape);
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 9fd0286..dc0d219 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -36,6 +36,7 @@
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xproto.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
+#include <X11/Xresource.h>
|
||||||
|
#ifdef XINERAMA
|
||||||
|
#include <X11/extensions/Xinerama.h>
|
||||||
|
#endif /* XINERAMA */
|
||||||
|
@@ -141,6 +142,19 @@ typedef struct {
|
||||||
|
int monitor;
|
||||||
|
} Rule;
|
||||||
|
|
||||||
|
+/* Xresources preferences */
|
||||||
|
+enum resource_type {
|
||||||
|
+ STRING = 0,
|
||||||
|
+ INTEGER = 1,
|
||||||
|
+ FLOAT = 2
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+typedef struct {
|
||||||
|
+ char *name;
|
||||||
|
+ enum resource_type type;
|
||||||
|
+ void *dst;
|
||||||
|
+} ResourcePref;
|
||||||
|
+
|
||||||
|
/* function declarations */
|
||||||
|
static void applyrules(Client *c);
|
||||||
|
static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
|
||||||
|
@@ -234,6 +248,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 load_xresources(void);
|
||||||
|
+static void resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst);
|
||||||
|
|
||||||
|
/* variables */
|
||||||
|
static const char broken[] = "broken";
|
||||||
|
@@ -2127,6 +2143,60 @@ zoom(const Arg *arg)
|
||||||
|
pop(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
|
||||||
|
+{
|
||||||
|
+ char *sdst = NULL;
|
||||||
|
+ int *idst = NULL;
|
||||||
|
+ float *fdst = NULL;
|
||||||
|
+
|
||||||
|
+ sdst = dst;
|
||||||
|
+ idst = dst;
|
||||||
|
+ fdst = dst;
|
||||||
|
+
|
||||||
|
+ char fullname[256];
|
||||||
|
+ char *type;
|
||||||
|
+ XrmValue ret;
|
||||||
|
+
|
||||||
|
+ snprintf(fullname, sizeof(fullname), "%s.%s", "dwm", name);
|
||||||
|
+ fullname[sizeof(fullname) - 1] = '\0';
|
||||||
|
+
|
||||||
|
+ XrmGetResource(db, fullname, "*", &type, &ret);
|
||||||
|
+ if (!(ret.addr == NULL || strncmp("String", type, 64)))
|
||||||
|
+ {
|
||||||
|
+ switch (rtype) {
|
||||||
|
+ case STRING:
|
||||||
|
+ strcpy(sdst, ret.addr);
|
||||||
|
+ break;
|
||||||
|
+ case INTEGER:
|
||||||
|
+ *idst = strtoul(ret.addr, NULL, 10);
|
||||||
|
+ break;
|
||||||
|
+ case FLOAT:
|
||||||
|
+ *fdst = strtof(ret.addr, NULL);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+load_xresources(void)
|
||||||
|
+{
|
||||||
|
+ Display *display;
|
||||||
|
+ char *resm;
|
||||||
|
+ XrmDatabase db;
|
||||||
|
+ ResourcePref *p;
|
||||||
|
+
|
||||||
|
+ display = XOpenDisplay(NULL);
|
||||||
|
+ resm = XResourceManagerString(display);
|
||||||
|
+ if (!resm)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ db = XrmGetStringDatabase(resm);
|
||||||
|
+ for (p = resources; p < resources + LENGTH(resources); p++)
|
||||||
|
+ resource_load(db, p->name, p->type, p->dst);
|
||||||
|
+ XCloseDisplay(display);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
@@ -2139,6 +2209,8 @@ main(int argc, char *argv[])
|
||||||
|
if (!(dpy = XOpenDisplay(NULL)))
|
||||||
|
die("dwm: cannot open display");
|
||||||
|
checkotherwm();
|
||||||
|
+ XrmInitialize();
|
||||||
|
+ load_xresources();
|
||||||
|
setup();
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
if (pledge("stdio rpath proc exec", NULL) == -1)
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
14
unfloat.c
Normal file
14
unfloat.c
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
void
|
||||||
|
unfloatvisible(const Arg *arg)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
for (c = selmon->clients; c; c = c->next)
|
||||||
|
if (ISVISIBLE(c) && c->isfloating)
|
||||||
|
c->isfloating = c->isfixed;
|
||||||
|
|
||||||
|
if (arg && arg->v)
|
||||||
|
setlayout(arg);
|
||||||
|
else
|
||||||
|
arrange(selmon);
|
||||||
|
}
|
135
util.c
135
util.c
@ -3,6 +3,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
@ -33,3 +35,136 @@ die(const char *fmt, ...) {
|
|||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
normalizepath(const char *path, char **normal)
|
||||||
|
{
|
||||||
|
size_t len = strlen(path);
|
||||||
|
*normal = (char *)malloc((len + 1) * sizeof(char));
|
||||||
|
const char *walk = path;
|
||||||
|
const char *match;
|
||||||
|
size_t newlen = 0;
|
||||||
|
|
||||||
|
while ((match = strchr(walk, '/'))) {
|
||||||
|
// Copy everything between match and walk
|
||||||
|
strncpy(*normal + newlen, walk, match - walk);
|
||||||
|
newlen += match - walk;
|
||||||
|
walk += match - walk;
|
||||||
|
|
||||||
|
// Skip all repeating slashes
|
||||||
|
while (*walk == '/')
|
||||||
|
walk++;
|
||||||
|
|
||||||
|
// If not last character in path
|
||||||
|
if (walk != path + len)
|
||||||
|
(*normal)[newlen++] = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
(*normal)[newlen++] = '\0';
|
||||||
|
|
||||||
|
// Copy remaining path
|
||||||
|
strcat(*normal, walk);
|
||||||
|
newlen += strlen(walk);
|
||||||
|
|
||||||
|
*normal = (char *)realloc(*normal, newlen * sizeof(char));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
parentdir(const char *path, char **parent)
|
||||||
|
{
|
||||||
|
char *normal;
|
||||||
|
char *walk;
|
||||||
|
|
||||||
|
normalizepath(path, &normal);
|
||||||
|
|
||||||
|
// Pointer to last '/'
|
||||||
|
if (!(walk = strrchr(normal, '/'))) {
|
||||||
|
free(normal);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get path up to last '/'
|
||||||
|
size_t len = walk - normal;
|
||||||
|
*parent = (char *)malloc((len + 1) * sizeof(char));
|
||||||
|
|
||||||
|
// Copy path up to last '/'
|
||||||
|
strncpy(*parent, normal, len);
|
||||||
|
// Add null char
|
||||||
|
(*parent)[len] = '\0';
|
||||||
|
|
||||||
|
free(normal);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
mkdirp(const char *path)
|
||||||
|
{
|
||||||
|
char *normal;
|
||||||
|
char *walk;
|
||||||
|
size_t normallen;
|
||||||
|
|
||||||
|
normalizepath(path, &normal);
|
||||||
|
normallen = strlen(normal);
|
||||||
|
walk = normal;
|
||||||
|
|
||||||
|
while (walk < normal + normallen + 1) {
|
||||||
|
// Get length from walk to next /
|
||||||
|
size_t n = strcspn(walk, "/");
|
||||||
|
|
||||||
|
// Skip path /
|
||||||
|
if (n == 0) {
|
||||||
|
walk++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Length of current path segment
|
||||||
|
size_t curpathlen = walk - normal + n;
|
||||||
|
char curpath[curpathlen + 1];
|
||||||
|
struct stat s;
|
||||||
|
|
||||||
|
// Copy path segment to stat
|
||||||
|
strncpy(curpath, normal, curpathlen);
|
||||||
|
strcpy(curpath + curpathlen, "");
|
||||||
|
int res = stat(curpath, &s);
|
||||||
|
|
||||||
|
if (res < 0) {
|
||||||
|
if (errno == ENOENT) {
|
||||||
|
DEBUG("Making directory %s\n", curpath);
|
||||||
|
if (mkdir(curpath, 0700) < 0) {
|
||||||
|
fprintf(stderr, "Failed to make directory %s\n", curpath);
|
||||||
|
perror("");
|
||||||
|
free(normal);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Error statting directory %s\n", curpath);
|
||||||
|
perror("");
|
||||||
|
free(normal);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Continue to next path segment
|
||||||
|
walk += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(normal);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
nullterminate(char **str, size_t *len)
|
||||||
|
{
|
||||||
|
if ((*str)[*len - 1] == '\0')
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
(*len)++;
|
||||||
|
*str = (char*)realloc(*str, *len * sizeof(char));
|
||||||
|
(*str)[*len - 1] = '\0';
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
10
util.h
10
util.h
@ -4,5 +4,15 @@
|
|||||||
#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))
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define DEBUG(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
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);
|
||||||
|
int normalizepath(const char *path, char **normal);
|
||||||
|
int mkdirp(const char *path);
|
||||||
|
int parentdir(const char *path, char **parent);
|
||||||
|
int nullterminate(char **str, size_t *len);
|
||||||
|
822
vanitygaps.c
Normal file
822
vanitygaps.c
Normal file
@ -0,0 +1,822 @@
|
|||||||
|
/* Key binding functions */
|
||||||
|
static void defaultgaps(const Arg *arg);
|
||||||
|
static void incrgaps(const Arg *arg);
|
||||||
|
static void incrigaps(const Arg *arg);
|
||||||
|
static void incrogaps(const Arg *arg);
|
||||||
|
static void incrohgaps(const Arg *arg);
|
||||||
|
static void incrovgaps(const Arg *arg);
|
||||||
|
static void incrihgaps(const Arg *arg);
|
||||||
|
static void incrivgaps(const Arg *arg);
|
||||||
|
static void togglegaps(const Arg *arg);
|
||||||
|
/* Layouts (delete the ones you do not need) */
|
||||||
|
static void bstack(Monitor *m);
|
||||||
|
static void bstackhoriz(Monitor *m);
|
||||||
|
static void centeredmaster(Monitor *m);
|
||||||
|
static void centeredfloatingmaster(Monitor *m);
|
||||||
|
static void deck(Monitor *m);
|
||||||
|
static void dwindle(Monitor *m);
|
||||||
|
static void fibonacci(Monitor *m, int s);
|
||||||
|
static void grid(Monitor *m);
|
||||||
|
static void nrowgrid(Monitor *m);
|
||||||
|
static void spiral(Monitor *m);
|
||||||
|
static void tile(Monitor *m);
|
||||||
|
/* Internals */
|
||||||
|
static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc);
|
||||||
|
static void getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr);
|
||||||
|
static void setgaps(int oh, int ov, int ih, int iv);
|
||||||
|
|
||||||
|
/* Settings */
|
||||||
|
#if !PERTAG_PATCH
|
||||||
|
static int enablegaps = 1;
|
||||||
|
#endif // PERTAG_PATCH
|
||||||
|
|
||||||
|
void
|
||||||
|
setgaps(int oh, int ov, int ih, int iv)
|
||||||
|
{
|
||||||
|
if (oh < 0) oh = 0;
|
||||||
|
if (ov < 0) ov = 0;
|
||||||
|
if (ih < 0) ih = 0;
|
||||||
|
if (iv < 0) iv = 0;
|
||||||
|
|
||||||
|
selmon->gappoh = oh;
|
||||||
|
selmon->gappov = ov;
|
||||||
|
selmon->gappih = ih;
|
||||||
|
selmon->gappiv = iv;
|
||||||
|
arrange(selmon);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
togglegaps(const Arg *arg)
|
||||||
|
{
|
||||||
|
#if PERTAG_PATCH
|
||||||
|
selmon->pertag->enablegaps[selmon->pertag->curtag] = !selmon->pertag->enablegaps[selmon->pertag->curtag];
|
||||||
|
#else
|
||||||
|
enablegaps = !enablegaps;
|
||||||
|
#endif // PERTAG_PATCH
|
||||||
|
arrange(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
defaultgaps(const Arg *arg)
|
||||||
|
{
|
||||||
|
setgaps(gappoh, gappov, gappih, gappiv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
incrgaps(const Arg *arg)
|
||||||
|
{
|
||||||
|
setgaps(
|
||||||
|
selmon->gappoh + arg->i,
|
||||||
|
selmon->gappov + arg->i,
|
||||||
|
selmon->gappih + arg->i,
|
||||||
|
selmon->gappiv + arg->i
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
incrigaps(const Arg *arg)
|
||||||
|
{
|
||||||
|
setgaps(
|
||||||
|
selmon->gappoh,
|
||||||
|
selmon->gappov,
|
||||||
|
selmon->gappih + arg->i,
|
||||||
|
selmon->gappiv + arg->i
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
incrogaps(const Arg *arg)
|
||||||
|
{
|
||||||
|
setgaps(
|
||||||
|
selmon->gappoh + arg->i,
|
||||||
|
selmon->gappov + arg->i,
|
||||||
|
selmon->gappih,
|
||||||
|
selmon->gappiv
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
incrohgaps(const Arg *arg)
|
||||||
|
{
|
||||||
|
setgaps(
|
||||||
|
selmon->gappoh + arg->i,
|
||||||
|
selmon->gappov,
|
||||||
|
selmon->gappih,
|
||||||
|
selmon->gappiv
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
incrovgaps(const Arg *arg)
|
||||||
|
{
|
||||||
|
setgaps(
|
||||||
|
selmon->gappoh,
|
||||||
|
selmon->gappov + arg->i,
|
||||||
|
selmon->gappih,
|
||||||
|
selmon->gappiv
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
incrihgaps(const Arg *arg)
|
||||||
|
{
|
||||||
|
setgaps(
|
||||||
|
selmon->gappoh,
|
||||||
|
selmon->gappov,
|
||||||
|
selmon->gappih + arg->i,
|
||||||
|
selmon->gappiv
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
incrivgaps(const Arg *arg)
|
||||||
|
{
|
||||||
|
setgaps(
|
||||||
|
selmon->gappoh,
|
||||||
|
selmon->gappov,
|
||||||
|
selmon->gappih,
|
||||||
|
selmon->gappiv + arg->i
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc)
|
||||||
|
{
|
||||||
|
unsigned int n, oe, ie;
|
||||||
|
#if PERTAG_PATCH
|
||||||
|
oe = ie = selmon->pertag->enablegaps[selmon->pertag->curtag];
|
||||||
|
#else
|
||||||
|
oe = ie = enablegaps;
|
||||||
|
#endif // PERTAG_PATCH
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
|
||||||
|
if (smartgaps && n == 1) {
|
||||||
|
oe = 0; // outer gaps disabled when only one client
|
||||||
|
}
|
||||||
|
|
||||||
|
*oh = m->gappoh*oe; // outer horizontal gap
|
||||||
|
*ov = m->gappov*oe; // outer vertical gap
|
||||||
|
*ih = m->gappih*ie; // inner horizontal gap
|
||||||
|
*iv = m->gappiv*ie; // inner vertical gap
|
||||||
|
*nc = n; // number of clients
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr)
|
||||||
|
{
|
||||||
|
unsigned int n;
|
||||||
|
float mfacts = 0, sfacts = 0;
|
||||||
|
int mtotal = 0, stotal = 0;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
|
||||||
|
if (n < m->nmaster)
|
||||||
|
mfacts += c->cfact;
|
||||||
|
else
|
||||||
|
sfacts += c->cfact;
|
||||||
|
|
||||||
|
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
|
||||||
|
if (n < m->nmaster)
|
||||||
|
mtotal += msize * (c->cfact / mfacts);
|
||||||
|
else
|
||||||
|
stotal += ssize * (c->cfact / sfacts);
|
||||||
|
|
||||||
|
*mf = mfacts; // total factor of master area
|
||||||
|
*sf = sfacts; // total factor of stack area
|
||||||
|
*mr = msize - mtotal; // the remainder (rest) of pixels after a cfacts master split
|
||||||
|
*sr = ssize - stotal; // the remainder (rest) of pixels after a cfacts stack split
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Layouts
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bottomstack layout + gaps
|
||||||
|
* https://dwm.suckless.org/patches/bottomstack/
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
bstack(Monitor *m)
|
||||||
|
{
|
||||||
|
unsigned int i, n;
|
||||||
|
int oh, ov, ih, iv;
|
||||||
|
int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
float mfacts, sfacts;
|
||||||
|
int mrest, srest;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sx = mx = m->wx + ov;
|
||||||
|
sy = my = m->wy + oh;
|
||||||
|
sh = mh = m->wh - 2*oh;
|
||||||
|
mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
|
||||||
|
sw = m->ww - 2*ov - iv * (n - m->nmaster - 1);
|
||||||
|
|
||||||
|
if (m->nmaster && n > m->nmaster) {
|
||||||
|
sh = (mh - ih) * (1 - m->mfact);
|
||||||
|
mh = mh - ih - sh;
|
||||||
|
sx = mx;
|
||||||
|
sy = my + mh + ih;
|
||||||
|
}
|
||||||
|
|
||||||
|
getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
|
||||||
|
|
||||||
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
|
||||||
|
if (i < m->nmaster) {
|
||||||
|
resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
|
||||||
|
mx += WIDTH(c) + iv;
|
||||||
|
} else {
|
||||||
|
resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
|
||||||
|
sx += WIDTH(c) + iv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bstackhoriz(Monitor *m)
|
||||||
|
{
|
||||||
|
unsigned int i, n;
|
||||||
|
int oh, ov, ih, iv;
|
||||||
|
int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
float mfacts, sfacts;
|
||||||
|
int mrest, srest;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sx = mx = m->wx + ov;
|
||||||
|
sy = my = m->wy + oh;
|
||||||
|
mh = m->wh - 2*oh;
|
||||||
|
sh = m->wh - 2*oh - ih * (n - m->nmaster - 1);
|
||||||
|
mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
|
||||||
|
sw = m->ww - 2*ov;
|
||||||
|
|
||||||
|
if (m->nmaster && n > m->nmaster) {
|
||||||
|
sh = (mh - ih) * (1 - m->mfact);
|
||||||
|
mh = mh - ih - sh;
|
||||||
|
sy = my + mh + ih;
|
||||||
|
sh = m->wh - mh - 2*oh - ih * (n - m->nmaster);
|
||||||
|
}
|
||||||
|
|
||||||
|
getfacts(m, mw, sh, &mfacts, &sfacts, &mrest, &srest);
|
||||||
|
|
||||||
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
|
||||||
|
if (i < m->nmaster) {
|
||||||
|
resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
|
||||||
|
mx += WIDTH(c) + iv;
|
||||||
|
} else {
|
||||||
|
resize(c, sx, sy, sw - (2*c->bw), sh * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
sy += HEIGHT(c) + ih;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Centred master layout + gaps
|
||||||
|
* https://dwm.suckless.org/patches/centeredmaster/
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
centeredmaster(Monitor *m)
|
||||||
|
{
|
||||||
|
unsigned int i, n;
|
||||||
|
int oh, ov, ih, iv;
|
||||||
|
int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
int lx = 0, ly = 0, lw = 0, lh = 0;
|
||||||
|
int rx = 0, ry = 0, rw = 0, rh = 0;
|
||||||
|
float mfacts = 0, lfacts = 0, rfacts = 0;
|
||||||
|
int mtotal = 0, ltotal = 0, rtotal = 0;
|
||||||
|
int mrest = 0, lrest = 0, rrest = 0;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* initialize areas */
|
||||||
|
mx = m->wx + ov;
|
||||||
|
my = m->wy + oh;
|
||||||
|
mh = m->wh - 2*oh - ih * ((!m->nmaster ? n : MIN(n, m->nmaster)) - 1);
|
||||||
|
mw = m->ww - 2*ov;
|
||||||
|
lh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - 1);
|
||||||
|
rh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - ((n - m->nmaster) % 2 ? 0 : 1));
|
||||||
|
|
||||||
|
if (m->nmaster && n > m->nmaster) {
|
||||||
|
/* go mfact box in the center if more than nmaster clients */
|
||||||
|
if (n - m->nmaster > 1) {
|
||||||
|
/* ||<-S->|<---M--->|<-S->|| */
|
||||||
|
mw = (m->ww - 2*ov - 2*iv) * m->mfact;
|
||||||
|
lw = (m->ww - mw - 2*ov - 2*iv) / 2;
|
||||||
|
rw = (m->ww - mw - 2*ov - 2*iv) - lw;
|
||||||
|
mx += lw + iv;
|
||||||
|
} else {
|
||||||
|
/* ||<---M--->|<-S->|| */
|
||||||
|
mw = (mw - iv) * m->mfact;
|
||||||
|
lw = 0;
|
||||||
|
rw = m->ww - mw - iv - 2*ov;
|
||||||
|
}
|
||||||
|
lx = m->wx + ov;
|
||||||
|
ly = m->wy + oh;
|
||||||
|
rx = mx + mw + iv;
|
||||||
|
ry = m->wy + oh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate facts */
|
||||||
|
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) {
|
||||||
|
if (!m->nmaster || n < m->nmaster)
|
||||||
|
mfacts += c->cfact;
|
||||||
|
else if ((n - m->nmaster) % 2)
|
||||||
|
lfacts += c->cfact; // total factor of left hand stack area
|
||||||
|
else
|
||||||
|
rfacts += c->cfact; // total factor of right hand stack area
|
||||||
|
}
|
||||||
|
|
||||||
|
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
|
||||||
|
if (!m->nmaster || n < m->nmaster)
|
||||||
|
mtotal += mh * (c->cfact / mfacts);
|
||||||
|
else if ((n - m->nmaster) % 2)
|
||||||
|
ltotal += lh * (c->cfact / lfacts);
|
||||||
|
else
|
||||||
|
rtotal += rh * (c->cfact / rfacts);
|
||||||
|
|
||||||
|
mrest = mh - mtotal;
|
||||||
|
lrest = lh - ltotal;
|
||||||
|
rrest = rh - rtotal;
|
||||||
|
|
||||||
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
|
||||||
|
if (!m->nmaster || i < m->nmaster) {
|
||||||
|
/* nmaster clients are stacked vertically, in the center of the screen */
|
||||||
|
resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
my += HEIGHT(c) + ih;
|
||||||
|
} else {
|
||||||
|
/* stack clients are stacked vertically */
|
||||||
|
if ((i - m->nmaster) % 2 ) {
|
||||||
|
resize(c, lx, ly, lw - (2*c->bw), lh * (c->cfact / lfacts) + ((i - 2*m->nmaster) < 2*lrest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
ly += HEIGHT(c) + ih;
|
||||||
|
} else {
|
||||||
|
resize(c, rx, ry, rw - (2*c->bw), rh * (c->cfact / rfacts) + ((i - 2*m->nmaster) < 2*rrest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
ry += HEIGHT(c) + ih;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
centeredfloatingmaster(Monitor *m)
|
||||||
|
{
|
||||||
|
unsigned int i, n;
|
||||||
|
float mfacts, sfacts;
|
||||||
|
float mivf = 1.0; // master inner vertical gap factor
|
||||||
|
int oh, ov, ih, iv, mrest, srest;
|
||||||
|
int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sx = mx = m->wx + ov;
|
||||||
|
sy = my = m->wy + oh;
|
||||||
|
sh = mh = m->wh - 2*oh;
|
||||||
|
mw = m->ww - 2*ov - iv*(n - 1);
|
||||||
|
sw = m->ww - 2*ov - iv*(n - m->nmaster - 1);
|
||||||
|
|
||||||
|
if (m->nmaster && n > m->nmaster) {
|
||||||
|
mivf = 0.8;
|
||||||
|
/* go mfact box in the center if more than nmaster clients */
|
||||||
|
if (m->ww > m->wh) {
|
||||||
|
mw = m->ww * m->mfact - iv*mivf*(MIN(n, m->nmaster) - 1);
|
||||||
|
mh = m->wh * 0.9;
|
||||||
|
} else {
|
||||||
|
mw = m->ww * 0.9 - iv*mivf*(MIN(n, m->nmaster) - 1);
|
||||||
|
mh = m->wh * m->mfact;
|
||||||
|
}
|
||||||
|
mx = m->wx + (m->ww - mw) / 2;
|
||||||
|
my = m->wy + (m->wh - mh - 2*oh) / 2;
|
||||||
|
|
||||||
|
sx = m->wx + ov;
|
||||||
|
sy = m->wy + oh;
|
||||||
|
sh = m->wh - 2*oh;
|
||||||
|
}
|
||||||
|
|
||||||
|
getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
|
||||||
|
|
||||||
|
for (i = 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 */
|
||||||
|
resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
|
||||||
|
mx += WIDTH(c) + iv*mivf;
|
||||||
|
} else {
|
||||||
|
/* stack clients are stacked horizontally */
|
||||||
|
resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
|
||||||
|
sx += WIDTH(c) + iv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deck layout + gaps
|
||||||
|
* https://dwm.suckless.org/patches/deck/
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
deck(Monitor *m)
|
||||||
|
{
|
||||||
|
unsigned int i, n;
|
||||||
|
int oh, ov, ih, iv;
|
||||||
|
int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
float mfacts, sfacts;
|
||||||
|
int mrest, srest;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sx = mx = m->wx + ov;
|
||||||
|
sy = my = m->wy + oh;
|
||||||
|
sh = mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
|
||||||
|
sw = mw = m->ww - 2*ov;
|
||||||
|
|
||||||
|
if (m->nmaster && n > m->nmaster) {
|
||||||
|
sw = (mw - iv) * (1 - m->mfact);
|
||||||
|
mw = mw - iv - sw;
|
||||||
|
sx = mx + mw + iv;
|
||||||
|
sh = m->wh - 2*oh;
|
||||||
|
}
|
||||||
|
|
||||||
|
getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
|
||||||
|
|
||||||
|
if (n - m->nmaster > 0) /* override layout symbol */
|
||||||
|
snprintf(m->ltsymbol, sizeof m->ltsymbol, "D %d", n - m->nmaster);
|
||||||
|
|
||||||
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
|
if (i < m->nmaster) {
|
||||||
|
resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
my += HEIGHT(c) + ih;
|
||||||
|
} else {
|
||||||
|
resize(c, sx, sy, sw - (2*c->bw), sh - (2*c->bw), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fibonacci layout + gaps
|
||||||
|
* https://dwm.suckless.org/patches/fibonacci/
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
fibonacci(Monitor *m, int s)
|
||||||
|
{
|
||||||
|
unsigned int i, n;
|
||||||
|
int nx, ny, nw, nh;
|
||||||
|
int oh, ov, ih, iv;
|
||||||
|
int nv, hrest = 0, wrest = 0, r = 1;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nx = m->wx + ov;
|
||||||
|
ny = m->wy + oh;
|
||||||
|
nw = m->ww - 2*ov;
|
||||||
|
nh = m->wh - 2*oh;
|
||||||
|
|
||||||
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
|
||||||
|
if (r) {
|
||||||
|
if ((i % 2 && (nh - ih) / 2 <= (bh + 2*c->bw))
|
||||||
|
|| (!(i % 2) && (nw - iv) / 2 <= (bh + 2*c->bw))) {
|
||||||
|
r = 0;
|
||||||
|
}
|
||||||
|
if (r && i < n - 1) {
|
||||||
|
if (i % 2) {
|
||||||
|
nv = (nh - ih) / 2;
|
||||||
|
hrest = nh - 2*nv - ih;
|
||||||
|
nh = nv;
|
||||||
|
} else {
|
||||||
|
nv = (nw - iv) / 2;
|
||||||
|
wrest = nw - 2*nv - iv;
|
||||||
|
nw = nv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((i % 4) == 2 && !s)
|
||||||
|
nx += nw + iv;
|
||||||
|
else if ((i % 4) == 3 && !s)
|
||||||
|
ny += nh + ih;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((i % 4) == 0) {
|
||||||
|
if (s) {
|
||||||
|
ny += nh + ih;
|
||||||
|
nh += hrest;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nh -= hrest;
|
||||||
|
ny -= nh + ih;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((i % 4) == 1) {
|
||||||
|
nx += nw + iv;
|
||||||
|
nw += wrest;
|
||||||
|
}
|
||||||
|
else if ((i % 4) == 2) {
|
||||||
|
ny += nh + ih;
|
||||||
|
nh += hrest;
|
||||||
|
if (i < n - 1)
|
||||||
|
nw += wrest;
|
||||||
|
}
|
||||||
|
else if ((i % 4) == 3) {
|
||||||
|
if (s) {
|
||||||
|
nx += nw + iv;
|
||||||
|
nw -= wrest;
|
||||||
|
} else {
|
||||||
|
nw -= wrest;
|
||||||
|
nx -= nw + iv;
|
||||||
|
nh += hrest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == 0) {
|
||||||
|
if (n != 1) {
|
||||||
|
nw = (m->ww - iv - 2*ov) - (m->ww - iv - 2*ov) * (1 - m->mfact);
|
||||||
|
wrest = 0;
|
||||||
|
}
|
||||||
|
ny = m->wy + oh;
|
||||||
|
}
|
||||||
|
else if (i == 1)
|
||||||
|
nw = m->ww - nw - iv - 2*ov;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
resize(c, nx, ny, nw - (2*c->bw), nh - (2*c->bw), False);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dwindle(Monitor *m)
|
||||||
|
{
|
||||||
|
fibonacci(m, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spiral(Monitor *m)
|
||||||
|
{
|
||||||
|
fibonacci(m, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gappless grid layout + gaps (ironically)
|
||||||
|
* https://dwm.suckless.org/patches/gaplessgrid/
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gaplessgrid(Monitor *m)
|
||||||
|
{
|
||||||
|
unsigned int i, n;
|
||||||
|
int x, y, cols, rows, ch, cw, cn, rn, rrest, crest; // counters
|
||||||
|
int oh, ov, ih, iv;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* grid dimensions */
|
||||||
|
for (cols = 0; cols <= n/2; cols++)
|
||||||
|
if (cols*cols >= n)
|
||||||
|
break;
|
||||||
|
if (n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */
|
||||||
|
cols = 2;
|
||||||
|
rows = n/cols;
|
||||||
|
cn = rn = 0; // reset column no, row no, client count
|
||||||
|
|
||||||
|
ch = (m->wh - 2*oh - ih * (rows - 1)) / rows;
|
||||||
|
cw = (m->ww - 2*ov - iv * (cols - 1)) / cols;
|
||||||
|
rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
|
||||||
|
crest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols;
|
||||||
|
x = m->wx + ov;
|
||||||
|
y = m->wy + oh;
|
||||||
|
|
||||||
|
for (i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) {
|
||||||
|
if (i/rows + 1 > cols - n%cols) {
|
||||||
|
rows = n/cols + 1;
|
||||||
|
ch = (m->wh - 2*oh - ih * (rows - 1)) / rows;
|
||||||
|
rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
|
||||||
|
}
|
||||||
|
resize(c,
|
||||||
|
x,
|
||||||
|
y + rn*(ch + ih) + MIN(rn, rrest),
|
||||||
|
cw + (cn < crest ? 1 : 0) - 2*c->bw,
|
||||||
|
ch + (rn < rrest ? 1 : 0) - 2*c->bw,
|
||||||
|
0);
|
||||||
|
rn++;
|
||||||
|
if (rn >= rows) {
|
||||||
|
rn = 0;
|
||||||
|
x += cw + ih + (cn < crest ? 1 : 0);
|
||||||
|
cn++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gridmode layout + gaps
|
||||||
|
* https://dwm.suckless.org/patches/gridmode/
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
grid(Monitor *m)
|
||||||
|
{
|
||||||
|
unsigned int i, n;
|
||||||
|
int cx, cy, cw, ch, cc, cr, chrest, cwrest, cols, rows;
|
||||||
|
int oh, ov, ih, iv;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
getgaps(m, &oh, &ov, &ih, &iv, &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 - 2*oh - ih * (rows - 1)) / (rows ? rows : 1);
|
||||||
|
cw = (m->ww - 2*ov - iv * (cols - 1)) / (cols ? cols : 1);
|
||||||
|
chrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
|
||||||
|
cwrest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols;
|
||||||
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
|
||||||
|
cc = i / rows;
|
||||||
|
cr = i % rows;
|
||||||
|
cx = m->wx + ov + cc * (cw + iv) + MIN(cc, cwrest);
|
||||||
|
cy = m->wy + oh + cr * (ch + ih) + MIN(cr, chrest);
|
||||||
|
resize(c, cx, cy, cw + (cc < cwrest ? 1 : 0) - 2*c->bw, ch + (cr < chrest ? 1 : 0) - 2*c->bw, False);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Horizontal grid layout + gaps
|
||||||
|
* https://dwm.suckless.org/patches/horizgrid/
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
horizgrid(Monitor *m) {
|
||||||
|
Client *c;
|
||||||
|
unsigned int n, i;
|
||||||
|
int oh, ov, ih, iv;
|
||||||
|
int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
int ntop, nbottom = 1;
|
||||||
|
float mfacts = 0, sfacts = 0;
|
||||||
|
int mrest, srest, mtotal = 0, stotal = 0;
|
||||||
|
|
||||||
|
/* Count windows */
|
||||||
|
getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (n <= 2)
|
||||||
|
ntop = n;
|
||||||
|
else {
|
||||||
|
ntop = n / 2;
|
||||||
|
nbottom = n - ntop;
|
||||||
|
}
|
||||||
|
sx = mx = m->wx + ov;
|
||||||
|
sy = my = m->wy + oh;
|
||||||
|
sh = mh = m->wh - 2*oh;
|
||||||
|
sw = mw = m->ww - 2*ov;
|
||||||
|
|
||||||
|
if (n > ntop) {
|
||||||
|
sh = (mh - ih) / 2;
|
||||||
|
mh = mh - ih - sh;
|
||||||
|
sy = my + mh + ih;
|
||||||
|
mw = m->ww - 2*ov - iv * (ntop - 1);
|
||||||
|
sw = m->ww - 2*ov - iv * (nbottom - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate facts */
|
||||||
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
|
if (i < ntop)
|
||||||
|
mfacts += c->cfact;
|
||||||
|
else
|
||||||
|
sfacts += c->cfact;
|
||||||
|
|
||||||
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
|
if (i < ntop)
|
||||||
|
mtotal += mh * (c->cfact / mfacts);
|
||||||
|
else
|
||||||
|
stotal += sw * (c->cfact / sfacts);
|
||||||
|
|
||||||
|
mrest = mh - mtotal;
|
||||||
|
srest = sw - stotal;
|
||||||
|
|
||||||
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
|
if (i < ntop) {
|
||||||
|
resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
|
||||||
|
mx += WIDTH(c) + iv;
|
||||||
|
} else {
|
||||||
|
resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - ntop) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
|
||||||
|
sx += WIDTH(c) + iv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* nrowgrid layout + gaps
|
||||||
|
* https://dwm.suckless.org/patches/nrowgrid/
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
nrowgrid(Monitor *m)
|
||||||
|
{
|
||||||
|
unsigned int n;
|
||||||
|
int ri = 0, ci = 0; /* counters */
|
||||||
|
int oh, ov, ih, iv; /* vanitygap settings */
|
||||||
|
unsigned int cx, cy, cw, ch; /* client geometry */
|
||||||
|
unsigned int uw = 0, uh = 0, uc = 0; /* utilization trackers */
|
||||||
|
unsigned int cols, rows = m->nmaster + 1;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
/* count clients */
|
||||||
|
getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
|
||||||
|
/* nothing to do here */
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* force 2 clients to always split vertically */
|
||||||
|
if (FORCE_VSPLIT && n == 2)
|
||||||
|
rows = 1;
|
||||||
|
|
||||||
|
/* never allow empty rows */
|
||||||
|
if (n < rows)
|
||||||
|
rows = n;
|
||||||
|
|
||||||
|
/* define first row */
|
||||||
|
cols = n / rows;
|
||||||
|
uc = cols;
|
||||||
|
cy = m->wy + oh;
|
||||||
|
ch = (m->wh - 2*oh - ih*(rows - 1)) / rows;
|
||||||
|
uh = ch;
|
||||||
|
|
||||||
|
for (c = nexttiled(m->clients); c; c = nexttiled(c->next), ci++) {
|
||||||
|
if (ci == cols) {
|
||||||
|
uw = 0;
|
||||||
|
ci = 0;
|
||||||
|
ri++;
|
||||||
|
|
||||||
|
/* next row */
|
||||||
|
cols = (n - uc) / (rows - ri);
|
||||||
|
uc += cols;
|
||||||
|
cy = m->wy + oh + uh + ih;
|
||||||
|
uh += ch + ih;
|
||||||
|
}
|
||||||
|
|
||||||
|
cx = m->wx + ov + uw;
|
||||||
|
cw = (m->ww - 2*ov - uw) / (cols - ci);
|
||||||
|
uw += cw + iv;
|
||||||
|
|
||||||
|
resize(c, cx, cy, cw - (2*c->bw), ch - (2*c->bw), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Default tile layout + gaps
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
tile(Monitor *m)
|
||||||
|
{
|
||||||
|
unsigned int i, n;
|
||||||
|
int oh, ov, ih, iv;
|
||||||
|
int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
float mfacts, sfacts;
|
||||||
|
int mrest, srest;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sx = mx = m->wx + ov;
|
||||||
|
sy = my = m->wy + oh;
|
||||||
|
mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
|
||||||
|
sh = m->wh - 2*oh - ih * (n - m->nmaster - 1);
|
||||||
|
sw = mw = m->ww - 2*ov;
|
||||||
|
|
||||||
|
if (m->nmaster && n > m->nmaster) {
|
||||||
|
sw = (mw - iv) * (1 - m->mfact);
|
||||||
|
mw = mw - iv - sw;
|
||||||
|
sx = mx + mw + iv;
|
||||||
|
}
|
||||||
|
|
||||||
|
getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
|
||||||
|
|
||||||
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
|
if (i < m->nmaster) {
|
||||||
|
resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
my += HEIGHT(c) + ih;
|
||||||
|
} else {
|
||||||
|
resize(c, sx, sy, sw - (2*c->bw), sh * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
sy += HEIGHT(c) + ih;
|
||||||
|
}
|
||||||
|
}
|
351
yajl_dumps.c
Normal file
351
yajl_dumps.c
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
#include "yajl_dumps.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
dump_tag(yajl_gen gen, const char *name, const int tag_mask)
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
|
YMAP(
|
||||||
|
YSTR("bit_mask"); YINT(tag_mask);
|
||||||
|
YSTR("name"); YSTR(name);
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dump_tags(yajl_gen gen, const char *tags[], int tags_len)
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
|
YARR(
|
||||||
|
for (int i = 0; i < tags_len; i++)
|
||||||
|
dump_tag(gen, tags[i], 1 << i);
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dump_client(yajl_gen gen, Client *c)
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
|
YMAP(
|
||||||
|
YSTR("name"); YSTR(c->name);
|
||||||
|
YSTR("tags"); YINT(c->tags);
|
||||||
|
YSTR("window_id"); YINT(c->win);
|
||||||
|
YSTR("monitor_number"); YINT(c->mon->num);
|
||||||
|
|
||||||
|
YSTR("geometry"); YMAP(
|
||||||
|
YSTR("current"); YMAP (
|
||||||
|
YSTR("x"); YINT(c->x);
|
||||||
|
YSTR("y"); YINT(c->y);
|
||||||
|
YSTR("width"); YINT(c->w);
|
||||||
|
YSTR("height"); YINT(c->h);
|
||||||
|
)
|
||||||
|
YSTR("old"); YMAP(
|
||||||
|
YSTR("x"); YINT(c->oldx);
|
||||||
|
YSTR("y"); YINT(c->oldy);
|
||||||
|
YSTR("width"); YINT(c->oldw);
|
||||||
|
YSTR("height"); YINT(c->oldh);
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
YSTR("size_hints"); YMAP(
|
||||||
|
YSTR("base"); YMAP(
|
||||||
|
YSTR("width"); YINT(c->basew);
|
||||||
|
YSTR("height"); YINT(c->baseh);
|
||||||
|
)
|
||||||
|
YSTR("step"); YMAP(
|
||||||
|
YSTR("width"); YINT(c->incw);
|
||||||
|
YSTR("height"); YINT(c->inch);
|
||||||
|
)
|
||||||
|
YSTR("max"); YMAP(
|
||||||
|
YSTR("width"); YINT(c->maxw);
|
||||||
|
YSTR("height"); YINT(c->maxh);
|
||||||
|
)
|
||||||
|
YSTR("min"); YMAP(
|
||||||
|
YSTR("width"); YINT(c->minw);
|
||||||
|
YSTR("height"); YINT(c->minh);
|
||||||
|
)
|
||||||
|
YSTR("aspect_ratio"); YMAP(
|
||||||
|
YSTR("min"); YDOUBLE(c->mina);
|
||||||
|
YSTR("max"); YDOUBLE(c->maxa);
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
YSTR("border_width"); YMAP(
|
||||||
|
YSTR("current"); YINT(c->bw);
|
||||||
|
YSTR("old"); YINT(c->oldbw);
|
||||||
|
)
|
||||||
|
|
||||||
|
YSTR("states"); YMAP(
|
||||||
|
YSTR("is_fixed"); YBOOL(c->isfixed);
|
||||||
|
YSTR("is_floating"); YBOOL(c->isfloating);
|
||||||
|
YSTR("is_urgent"); YBOOL(c->isurgent);
|
||||||
|
YSTR("never_focus"); YBOOL(c->neverfocus);
|
||||||
|
YSTR("old_state"); YBOOL(c->oldstate);
|
||||||
|
YSTR("is_fullscreen"); YBOOL(c->isfullscreen);
|
||||||
|
)
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dump_monitor(yajl_gen gen, Monitor *mon, int is_selected)
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
|
YMAP(
|
||||||
|
YSTR("master_factor"); YDOUBLE(mon->mfact);
|
||||||
|
YSTR("num_master"); YINT(mon->nmaster);
|
||||||
|
YSTR("num"); YINT(mon->num);
|
||||||
|
YSTR("is_selected"); YBOOL(is_selected);
|
||||||
|
|
||||||
|
YSTR("monitor_geometry"); YMAP(
|
||||||
|
YSTR("x"); YINT(mon->mx);
|
||||||
|
YSTR("y"); YINT(mon->my);
|
||||||
|
YSTR("width"); YINT(mon->mw);
|
||||||
|
YSTR("height"); YINT(mon->mh);
|
||||||
|
)
|
||||||
|
|
||||||
|
YSTR("window_geometry"); YMAP(
|
||||||
|
YSTR("x"); YINT(mon->wx);
|
||||||
|
YSTR("y"); YINT(mon->wy);
|
||||||
|
YSTR("width"); YINT(mon->ww);
|
||||||
|
YSTR("height"); YINT(mon->wh);
|
||||||
|
)
|
||||||
|
|
||||||
|
YSTR("tagset"); YMAP(
|
||||||
|
YSTR("current"); YINT(mon->tagset[mon->seltags]);
|
||||||
|
YSTR("old"); YINT(mon->tagset[mon->seltags ^ 1]);
|
||||||
|
)
|
||||||
|
|
||||||
|
YSTR("tag_state"); dump_tag_state(gen, mon->tagstate);
|
||||||
|
|
||||||
|
YSTR("clients"); YMAP(
|
||||||
|
YSTR("selected"); YINT(mon->sel ? mon->sel->win : 0);
|
||||||
|
YSTR("stack"); YARR(
|
||||||
|
for (Client* c = mon->stack; c; c = c->snext)
|
||||||
|
YINT(c->win);
|
||||||
|
)
|
||||||
|
YSTR("all"); YARR(
|
||||||
|
for (Client* c = mon->clients; c; c = c->next)
|
||||||
|
YINT(c->win);
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
YSTR("layout"); YMAP(
|
||||||
|
YSTR("symbol"); YMAP(
|
||||||
|
YSTR("current"); YSTR(mon->ltsymbol);
|
||||||
|
YSTR("old"); YSTR(mon->lastltsymbol);
|
||||||
|
)
|
||||||
|
YSTR("address"); YMAP(
|
||||||
|
YSTR("current"); YINT((uintptr_t)mon->lt[mon->sellt]);
|
||||||
|
YSTR("old"); YINT((uintptr_t)mon->lt[mon->sellt ^ 1]);
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
YSTR("bar"); YMAP(
|
||||||
|
YSTR("y"); YINT(mon->by);
|
||||||
|
YSTR("is_shown"); YBOOL(mon->showbar);
|
||||||
|
YSTR("is_top"); YBOOL(mon->topbar);
|
||||||
|
YSTR("window_id"); YINT(mon->barwin);
|
||||||
|
)
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dump_monitors(yajl_gen gen, Monitor *mons, Monitor *selmon)
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
|
YARR(
|
||||||
|
for (Monitor *mon = mons; mon; mon = mon->next) {
|
||||||
|
if (mon == selmon)
|
||||||
|
dump_monitor(gen, mon, 1);
|
||||||
|
else
|
||||||
|
dump_monitor(gen, mon, 0);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dump_layouts(yajl_gen gen, const Layout layouts[], const int layouts_len)
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
|
YARR(
|
||||||
|
for (int i = 0; i < layouts_len; i++) {
|
||||||
|
YMAP(
|
||||||
|
// Check for a NULL pointer. The cycle layouts patch adds an entry at
|
||||||
|
// the end of the layouts array with a NULL pointer for the symbol
|
||||||
|
YSTR("symbol"); YSTR((layouts[i].symbol ? layouts[i].symbol : ""));
|
||||||
|
YSTR("address"); YINT((uintptr_t)(layouts + i));
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dump_tag_state(yajl_gen gen, TagState state)
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
|
YMAP(
|
||||||
|
YSTR("selected"); YINT(state.selected);
|
||||||
|
YSTR("occupied"); YINT(state.occupied);
|
||||||
|
YSTR("urgent"); YINT(state.urgent);
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dump_tag_event(yajl_gen gen, int mon_num, TagState old_state,
|
||||||
|
TagState new_state)
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
|
YMAP(
|
||||||
|
YSTR("tag_change_event"); YMAP(
|
||||||
|
YSTR("monitor_number"); YINT(mon_num);
|
||||||
|
YSTR("old_state"); dump_tag_state(gen, old_state);
|
||||||
|
YSTR("new_state"); dump_tag_state(gen, new_state);
|
||||||
|
)
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dump_client_focus_change_event(yajl_gen gen, Client *old_client,
|
||||||
|
Client *new_client, int mon_num)
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
|
YMAP(
|
||||||
|
YSTR("client_focus_change_event"); YMAP(
|
||||||
|
YSTR("monitor_number"); YINT(mon_num);
|
||||||
|
YSTR("old_win_id"); old_client == NULL ? YNULL() : YINT(old_client->win);
|
||||||
|
YSTR("new_win_id"); new_client == NULL ? YNULL() : YINT(new_client->win);
|
||||||
|
)
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dump_layout_change_event(yajl_gen gen, const int mon_num,
|
||||||
|
const char *old_symbol, const Layout *old_layout,
|
||||||
|
const char *new_symbol, const Layout *new_layout)
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
|
YMAP(
|
||||||
|
YSTR("layout_change_event"); YMAP(
|
||||||
|
YSTR("monitor_number"); YINT(mon_num);
|
||||||
|
YSTR("old_symbol"); YSTR(old_symbol);
|
||||||
|
YSTR("old_address"); YINT((uintptr_t)old_layout);
|
||||||
|
YSTR("new_symbol"); YSTR(new_symbol);
|
||||||
|
YSTR("new_address"); YINT((uintptr_t)new_layout);
|
||||||
|
)
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dump_monitor_focus_change_event(yajl_gen gen, const int last_mon_num,
|
||||||
|
const int new_mon_num)
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
|
YMAP(
|
||||||
|
YSTR("monitor_focus_change_event"); YMAP(
|
||||||
|
YSTR("old_monitor_number"); YINT(last_mon_num);
|
||||||
|
YSTR("new_monitor_number"); YINT(new_mon_num);
|
||||||
|
)
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dump_focused_title_change_event(yajl_gen gen, const int mon_num,
|
||||||
|
const Window client_id, const char *old_name,
|
||||||
|
const char *new_name)
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
|
YMAP(
|
||||||
|
YSTR("focused_title_change_event"); YMAP(
|
||||||
|
YSTR("monitor_number"); YINT(mon_num);
|
||||||
|
YSTR("client_window_id"); YINT(client_id);
|
||||||
|
YSTR("old_name"); YSTR(old_name);
|
||||||
|
YSTR("new_name"); YSTR(new_name);
|
||||||
|
)
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dump_client_state(yajl_gen gen, const ClientState *state)
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
|
YMAP(
|
||||||
|
YSTR("old_state"); YBOOL(state->oldstate);
|
||||||
|
YSTR("is_fixed"); YBOOL(state->isfixed);
|
||||||
|
YSTR("is_floating"); YBOOL(state->isfloating);
|
||||||
|
YSTR("is_fullscreen"); YBOOL(state->isfullscreen);
|
||||||
|
YSTR("is_urgent"); YBOOL(state->isurgent);
|
||||||
|
YSTR("never_focus"); YBOOL(state->neverfocus);
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dump_focused_state_change_event(yajl_gen gen, const int mon_num,
|
||||||
|
const Window client_id,
|
||||||
|
const ClientState *old_state,
|
||||||
|
const ClientState *new_state)
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
|
YMAP(
|
||||||
|
YSTR("focused_state_change_event"); YMAP(
|
||||||
|
YSTR("monitor_number"); YINT(mon_num);
|
||||||
|
YSTR("client_window_id"); YINT(client_id);
|
||||||
|
YSTR("old_state"); dump_client_state(gen, old_state);
|
||||||
|
YSTR("new_state"); dump_client_state(gen, new_state);
|
||||||
|
)
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
dump_error_message(yajl_gen gen, const char *reason)
|
||||||
|
{
|
||||||
|
// clang-format off
|
||||||
|
YMAP(
|
||||||
|
YSTR("result"); YSTR("error");
|
||||||
|
YSTR("reason"); YSTR(reason);
|
||||||
|
)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
65
yajl_dumps.h
Normal file
65
yajl_dumps.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#ifndef YAJL_DUMPS_H_
|
||||||
|
#define YAJL_DUMPS_H_
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <yajl/yajl_gen.h>
|
||||||
|
|
||||||
|
#define YSTR(str) yajl_gen_string(gen, (unsigned char *)str, strlen(str))
|
||||||
|
#define YINT(num) yajl_gen_integer(gen, num)
|
||||||
|
#define YDOUBLE(num) yajl_gen_double(gen, num)
|
||||||
|
#define YBOOL(v) yajl_gen_bool(gen, v)
|
||||||
|
#define YNULL() yajl_gen_null(gen)
|
||||||
|
#define YARR(body) \
|
||||||
|
{ \
|
||||||
|
yajl_gen_array_open(gen); \
|
||||||
|
body; \
|
||||||
|
yajl_gen_array_close(gen); \
|
||||||
|
}
|
||||||
|
#define YMAP(body) \
|
||||||
|
{ \
|
||||||
|
yajl_gen_map_open(gen); \
|
||||||
|
body; \
|
||||||
|
yajl_gen_map_close(gen); \
|
||||||
|
}
|
||||||
|
|
||||||
|
int dump_tag(yajl_gen gen, const char *name, const int tag_mask);
|
||||||
|
|
||||||
|
int dump_tags(yajl_gen gen, const char *tags[], int tags_len);
|
||||||
|
|
||||||
|
int dump_client(yajl_gen gen, Client *c);
|
||||||
|
|
||||||
|
int dump_monitor(yajl_gen gen, Monitor *mon, int is_selected);
|
||||||
|
|
||||||
|
int dump_monitors(yajl_gen gen, Monitor *mons, Monitor *selmon);
|
||||||
|
|
||||||
|
int dump_layouts(yajl_gen gen, const Layout layouts[], const int layouts_len);
|
||||||
|
|
||||||
|
int dump_tag_state(yajl_gen gen, TagState state);
|
||||||
|
|
||||||
|
int dump_tag_event(yajl_gen gen, int mon_num, TagState old_state,
|
||||||
|
TagState new_state);
|
||||||
|
|
||||||
|
int dump_client_focus_change_event(yajl_gen gen, Client *old_client,
|
||||||
|
Client *new_client, int mon_num);
|
||||||
|
|
||||||
|
int dump_layout_change_event(yajl_gen gen, const int mon_num,
|
||||||
|
const char *old_symbol, const Layout *old_layout,
|
||||||
|
const char *new_symbol, const Layout *new_layout);
|
||||||
|
|
||||||
|
int dump_monitor_focus_change_event(yajl_gen gen, const int last_mon_num,
|
||||||
|
const int new_mon_num);
|
||||||
|
|
||||||
|
int dump_focused_title_change_event(yajl_gen gen, const int mon_num,
|
||||||
|
const Window client_id,
|
||||||
|
const char *old_name, const char *new_name);
|
||||||
|
|
||||||
|
int dump_client_state(yajl_gen gen, const ClientState *state);
|
||||||
|
|
||||||
|
int dump_focused_state_change_event(yajl_gen gen, const int mon_num,
|
||||||
|
const Window client_id,
|
||||||
|
const ClientState *old_state,
|
||||||
|
const ClientState *new_state);
|
||||||
|
|
||||||
|
int dump_error_message(yajl_gen gen, const char *reason);
|
||||||
|
|
||||||
|
#endif // YAJL_DUMPS_H_
|
Loading…
x
Reference in New Issue
Block a user