suicide
This commit is contained in:
parent
6bb6d198f1
commit
57b69302f1
196 changed files with 6596 additions and 128 deletions
38
dwm/LICENSE
Normal file
38
dwm/LICENSE
Normal file
|
@ -0,0 +1,38 @@
|
|||
MIT/X Consortium License
|
||||
|
||||
© 2006-2019 Anselm R Garbe <anselm@garbe.ca>
|
||||
© 2006-2009 Jukka Salmi <jukka at salmi dot ch>
|
||||
© 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
|
||||
© 2007-2011 Peter Hartlich <sgkkr at hartlich dot com>
|
||||
© 2007-2009 Szabolcs Nagy <nszabolcs at gmail dot com>
|
||||
© 2007-2009 Christof Musik <christof at sendfax dot de>
|
||||
© 2007-2009 Premysl Hruby <dfenze at gmail dot com>
|
||||
© 2007-2008 Enno Gottox Boland <gottox at s01 dot de>
|
||||
© 2008 Martin Hurton <martin dot hurton at gmail dot com>
|
||||
© 2008 Neale Pickett <neale dot woozle dot org>
|
||||
© 2009 Mate Nagy <mnagy at port70 dot net>
|
||||
© 2010-2016 Hiltjo Posthuma <hiltjo@codemadness.org>
|
||||
© 2010-2012 Connor Lane Smith <cls@lubutu.com>
|
||||
© 2011 Christoph Lohmann <20h@r-36.net>
|
||||
© 2015-2016 Quentin Rameau <quinq@fifth.space>
|
||||
© 2015-2016 Eric Pruitt <eric.pruitt@gmail.com>
|
||||
© 2016-2017 Markus Teich <markus.teich@stusta.mhn.de>
|
||||
© 2020-2022 Chris Down <chris@chrisdown.name>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
67
dwm/Makefile
Normal file
67
dwm/Makefile
Normal file
|
@ -0,0 +1,67 @@
|
|||
# dwm - dynamic window manager
|
||||
# See LICENSE file for copyright and license details.
|
||||
|
||||
include config.mk
|
||||
|
||||
SRC = drw.c dwm.c util.c
|
||||
OBJ = ${SRC:.c=.o}
|
||||
|
||||
# FreeBSD users, prefix all ifdef, else and endif statements with a . for this to work (e.g. .ifdef)
|
||||
|
||||
ifdef YAJLLIBS
|
||||
all: options dwm dwm-msg
|
||||
else
|
||||
all: options dwm
|
||||
endif
|
||||
|
||||
options:
|
||||
@echo dwm build options:
|
||||
@echo "CFLAGS = ${CFLAGS}"
|
||||
@echo "LDFLAGS = ${LDFLAGS}"
|
||||
@echo "CC = ${CC}"
|
||||
|
||||
.c.o:
|
||||
${CC} -c ${CFLAGS} $<
|
||||
|
||||
${OBJ}: config.h config.mk
|
||||
|
||||
dwm: ${OBJ}
|
||||
${CC} -o $@ ${OBJ} ${LDFLAGS}
|
||||
|
||||
ifdef YAJLLIBS
|
||||
dwm-msg:
|
||||
${CC} -o $@ patch/ipc/dwm-msg.c ${LDFLAGS}
|
||||
endif
|
||||
|
||||
clean:
|
||||
rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
|
||||
rm -f dwm-msg
|
||||
|
||||
dist: clean
|
||||
mkdir -p dwm-${VERSION}
|
||||
cp -R LICENSE Makefile README config.def.h config.mk\
|
||||
dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION}
|
||||
tar -cf dwm-${VERSION}.tar dwm-${VERSION}
|
||||
gzip dwm-${VERSION}.tar
|
||||
rm -rf dwm-${VERSION}
|
||||
|
||||
install: all
|
||||
mkdir -p ${DESTDIR}${PREFIX}/bin
|
||||
cp -f dwm ${DESTDIR}${PREFIX}/bin
|
||||
ifdef YAJLLIBS
|
||||
cp -f dwm-msg ${DESTDIR}${PREFIX}/bin
|
||||
endif
|
||||
cp -f patch/dwmc ${DESTDIR}${PREFIX}/bin
|
||||
chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
|
||||
ifdef YAJLLIBS
|
||||
chmod 755 ${DESTDIR}${PREFIX}/bin/dwm-msg
|
||||
endif
|
||||
mkdir -p ${DESTDIR}${MANPREFIX}/man1
|
||||
sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
|
||||
chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1
|
||||
|
||||
uninstall:
|
||||
rm -f ${DESTDIR}${PREFIX}/bin/dwm\
|
||||
${DESTDIR}${MANPREFIX}/man1/dwm.1
|
||||
|
||||
.PHONY: all options clean dist install uninstall
|
58
dwm/README.md
Normal file
58
dwm/README.md
Normal file
|
@ -0,0 +1,58 @@
|
|||
# DWM
|
||||
DWM is my favorite window manager by far due to its simplicity, portability, and low resource usage. However, it requires a decent amount of tweaking if you want to be able to use it for standard tasks. That's what I've aimed to do here, creating a user-friendly environment and memorable keybinds.
|
||||
|
||||
## Compiling
|
||||
### Dependencies
|
||||
X11, Xinerama, xcb, freetype
|
||||
### Instructions
|
||||
Run `./configure` to properly set up `config.mk`.
|
||||
#### Linux
|
||||
`make && sudo make install`
|
||||
#### FreeBSD, OpenBSD
|
||||
`gmake && doas gmake install`
|
||||
|
||||
## Patches applied
|
||||
```
|
||||
dwmblocks (statuscmd)
|
||||
dwmblocks (SIGUSR1)
|
||||
bar layout symbol -- show window layout in status bar
|
||||
bar status -- show status in bar
|
||||
bar tag symbols -- show tag symbols in bar
|
||||
bar window title -- show window title in bar
|
||||
bar alpha -- semi-transparency on bar
|
||||
bar hide vacant tags -- hide tags with no windows
|
||||
attach aside -- add new windows to stack instead of master
|
||||
cool autostart -- execute commands on start and have processes owned by dwm
|
||||
dwmc -- use dwmc program to execute dwm commands (for scriptability)
|
||||
fullscreen -- applies monocle layout on active window and hides bar
|
||||
moveresize -- resize dwm windows with keybinds
|
||||
movestack -- allows to move windows in stack and to become master
|
||||
no transparent borders -- make window borders always solid
|
||||
scratchpads -- allow for scratchpad terminals
|
||||
swallow -- hide terminal window when it spawns a window and freezes itself (not working on OpenBSD)
|
||||
togglefullscreen -- use a keybind to make a window fullscreen or not
|
||||
vanitygaps -- add gaps between all windows
|
||||
```
|
||||
|
||||
## Software Made to Work With This
|
||||
- [DWMBlocks](https://github.com/swindlesmccoop/dwmblocks)
|
||||
- [DMenu](https://github.com/swindlesmccoop/dmenu)
|
||||
- [ST](https://github.com/swindlesmccoop/st)
|
||||
|
||||
## Keybinds
|
||||
All keybinds can be found by running `man dwm`, but here are the important ones:
|
||||
- `Super + Enter` - Spawn terminal (st)
|
||||
- `Super + Shift + Enter`, `F12` - Toggle scratchpad terminal
|
||||
- `Super + h/l` - Shrink/enlarge master window
|
||||
- `Super + d` - dmenu\_run (program launcher)
|
||||
- `Super + q` - Kill window
|
||||
- `Super + b` - Toggle status bar
|
||||
- `Super + f` - Toggle fullscreen
|
||||
- `Super + m` - Set window as master
|
||||
- `Super + o/O` - Increase/decrease number of masters
|
||||
- `Super + j/k` - Move focus down/up
|
||||
- `Super + J/K` - Move window in stack down/up
|
||||
- `Super + E`, `Super + Q` - Kill DWM
|
||||
- `Super + Space` - Set all windows to Floating mode
|
||||
- `Super + [Arrow]` - Move window in direction of arrow pressed
|
||||
- `Super + Shift + [Arrow]` - Expand/shrink window in direction of arrow pressed
|
389
dwm/config.h
Normal file
389
dwm/config.h
Normal file
|
@ -0,0 +1,389 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
/* appearance */
|
||||
static const unsigned int borderpx = 3; /* border pixel of windows */
|
||||
static const unsigned int snap = 0; /* snap pixel */
|
||||
static const int swallowfloating = 1; /* 1 means swallow floating windows by default */
|
||||
static const unsigned int gappih = 10; /* 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 const int smartgaps_fact = 1; /* gap factor when there is only one client; 0 = no gaps, 3 = 3x outer gaps */
|
||||
static const int showbar = 1; /* 0 means no bar */
|
||||
static const int topbar = 1; /* 0 means bottom bar */
|
||||
/* Status is to be shown on: -1 (all monitors), 0 (a specific monitor by index), 'A' (active monitor) */
|
||||
static const int statusmon = 'A';
|
||||
|
||||
/* Indicators: see patch/bar_indicators.h for options */
|
||||
static int tagindicatortype = INDICATOR_NONE;
|
||||
static int tiledindicatortype = INDICATOR_NONE;
|
||||
static int floatindicatortype = INDICATOR_NONE;
|
||||
static const char *fonts[] = { "monospace:size=12" };
|
||||
static const char dmenufont[] = "monospace:size=12";
|
||||
|
||||
static char c000000[] = "#000000";
|
||||
|
||||
static char normfgcolor[] = "#bbbbbb";
|
||||
static char normbgcolor[] = "#222222";
|
||||
static char normbordercolor[] = "#444444";
|
||||
static char normfloatcolor[] = "#db8fd9";
|
||||
|
||||
static char selfgcolor[] = "#eeeeee";
|
||||
static char selbgcolor[] = "#005577";
|
||||
static char selbordercolor[] = "#005577";
|
||||
static char selfloatcolor[] = "#005577";
|
||||
|
||||
static char titlenormfgcolor[] = "#bbbbbb";
|
||||
static char titlenormbgcolor[] = "#222222";
|
||||
static char titlenormbordercolor[] = "#444444";
|
||||
static char titlenormfloatcolor[] = "#db8fd9";
|
||||
|
||||
static char titleselfgcolor[] = "#eeeeee";
|
||||
static char titleselbgcolor[] = "#005577";
|
||||
static char titleselbordercolor[] = "#005577";
|
||||
static char titleselfloatcolor[] = "#005577";
|
||||
|
||||
static char tagsnormfgcolor[] = "#bbbbbb";
|
||||
static char tagsnormbgcolor[] = "#222222";
|
||||
static char tagsnormbordercolor[] = "#444444";
|
||||
static char tagsnormfloatcolor[] = "#db8fd9";
|
||||
|
||||
static char tagsselfgcolor[] = "#eeeeee";
|
||||
static char tagsselbgcolor[] = "#005577";
|
||||
static char tagsselbordercolor[] = "#005577";
|
||||
static char tagsselfloatcolor[] = "#005577";
|
||||
|
||||
static char hidnormfgcolor[] = "#005577";
|
||||
static char hidselfgcolor[] = "#227799";
|
||||
static char hidnormbgcolor[] = "#222222";
|
||||
static char hidselbgcolor[] = "#222222";
|
||||
|
||||
static char urgfgcolor[] = "#bbbbbb";
|
||||
static char urgbgcolor[] = "#222222";
|
||||
static char urgbordercolor[] = "#ff0000";
|
||||
static char urgfloatcolor[] = "#db8fd9";
|
||||
|
||||
|
||||
|
||||
static const unsigned int baralpha = 0xff;
|
||||
static const unsigned int borderalpha = OPAQUE;
|
||||
static const unsigned int alphas[][3] = {
|
||||
/* fg bg border */
|
||||
[SchemeNorm] = { OPAQUE, baralpha, borderalpha },
|
||||
[SchemeSel] = { OPAQUE, baralpha, borderalpha },
|
||||
[SchemeTitleNorm] = { OPAQUE, baralpha, borderalpha },
|
||||
[SchemeTitleSel] = { OPAQUE, baralpha, borderalpha },
|
||||
[SchemeTagsNorm] = { OPAQUE, baralpha, borderalpha },
|
||||
[SchemeTagsSel] = { OPAQUE, baralpha, borderalpha },
|
||||
[SchemeHidNorm] = { OPAQUE, baralpha, borderalpha },
|
||||
[SchemeHidSel] = { OPAQUE, baralpha, borderalpha },
|
||||
[SchemeUrg] = { OPAQUE, baralpha, borderalpha },
|
||||
};
|
||||
|
||||
static char *colors[][ColCount] = {
|
||||
/* fg bg border float */
|
||||
[SchemeNorm] = { normfgcolor, normbgcolor, normbordercolor, normfloatcolor },
|
||||
[SchemeSel] = { selfgcolor, selbgcolor, selbordercolor, selfloatcolor },
|
||||
[SchemeTitleNorm] = { titlenormfgcolor, titlenormbgcolor, titlenormbordercolor, titlenormfloatcolor },
|
||||
[SchemeTitleSel] = { titleselfgcolor, titleselbgcolor, titleselbordercolor, titleselfloatcolor },
|
||||
[SchemeTagsNorm] = { tagsnormfgcolor, tagsnormbgcolor, tagsnormbordercolor, tagsnormfloatcolor },
|
||||
[SchemeTagsSel] = { tagsselfgcolor, tagsselbgcolor, tagsselbordercolor, tagsselfloatcolor },
|
||||
[SchemeHidNorm] = { hidnormfgcolor, hidnormbgcolor, c000000, c000000 },
|
||||
[SchemeHidSel] = { hidselfgcolor, hidselbgcolor, c000000, c000000 },
|
||||
[SchemeUrg] = { urgfgcolor, urgbgcolor, urgbordercolor, urgfloatcolor },
|
||||
};
|
||||
|
||||
|
||||
|
||||
static const char *const autostart[] = {
|
||||
//"sh", "-c", "$HOME/.xprofile", NULL,
|
||||
NULL /* terminate */
|
||||
};
|
||||
|
||||
const char *spcmd1[] = {"st", "-n", "spterm", "-g", "120x34", NULL };
|
||||
static Sp scratchpads[] = {
|
||||
/* name cmd */
|
||||
{"spterm", spcmd1},
|
||||
};
|
||||
|
||||
/* Tags
|
||||
* In a traditional dwm the number of tags in use can be changed simply by changing the number
|
||||
* of strings in the tags array. This build does things a bit different which has some added
|
||||
* benefits. If you need to change the number of tags here then change the NUMTAGS macro in dwm.c.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* 1) static char *tagicons[][NUMTAGS*2] = {
|
||||
* [DEFAULT_TAGS] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I" },
|
||||
* }
|
||||
*
|
||||
* 2) static char *tagicons[][1] = {
|
||||
* [DEFAULT_TAGS] = { "•" },
|
||||
* }
|
||||
*
|
||||
* The first example would result in the tags on the first monitor to be 1 through 9, while the
|
||||
* tags for the second monitor would be named A through I. A third monitor would start again at
|
||||
* 1 through 9 while the tags on a fourth monitor would also be named A through I. Note the tags
|
||||
* count of NUMTAGS*2 in the array initialiser which defines how many tag text / icon exists in
|
||||
* the array. This can be changed to *3 to add separate icons for a third monitor.
|
||||
*
|
||||
* For the second example each tag would be represented as a bullet point. Both cases work the
|
||||
* same from a technical standpoint - the icon index is derived from the tag index and the monitor
|
||||
* index. If the icon index is is greater than the number of tag icons then it will wrap around
|
||||
* until it an icon matches. Similarly if there are two tag icons then it would alternate between
|
||||
* them. This works seamlessly with alternative tags and alttagsdecoration patches.
|
||||
*/
|
||||
static char *tagicons[][NUMTAGS] = {
|
||||
[DEFAULT_TAGS] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" },
|
||||
[ALTERNATIVE_TAGS] = { "A", "B", "C", "D", "E", "F", "G", "H", "I" },
|
||||
[ALT_TAGS_DECORATION] = { "<1>", "<2>", "<3>", "<4>", "<5>", "<6>", "<7>", "<8>", "<9>" },
|
||||
};
|
||||
|
||||
|
||||
/* There are two options when it comes to per-client rules:
|
||||
* - a typical struct table or
|
||||
* - using the RULE macro
|
||||
*
|
||||
* A traditional struct table looks like this:
|
||||
* // class instance title wintype tags mask isfloating monitor
|
||||
* { "Gimp", NULL, NULL, NULL, 1 << 4, 0, -1 },
|
||||
* { "Firefox", NULL, NULL, NULL, 1 << 7, 0, -1 },
|
||||
*
|
||||
* The RULE macro has the default values set for each field allowing you to only
|
||||
* specify the values that are relevant for your rule, e.g.
|
||||
*
|
||||
* RULE(.class = "Gimp", .tags = 1 << 4)
|
||||
* RULE(.class = "Firefox", .tags = 1 << 7)
|
||||
*
|
||||
* Refer to the Rule struct definition for the list of available fields depending on
|
||||
* the patches you enable.
|
||||
*/
|
||||
static const Rule rules[] = {
|
||||
/* xprop(1):
|
||||
* WM_CLASS(STRING) = instance, class
|
||||
* WM_NAME(STRING) = title
|
||||
* WM_WINDOW_ROLE(STRING) = role
|
||||
* _NET_WM_WINDOW_TYPE(ATOM) = wintype
|
||||
*/
|
||||
RULE(.wintype = WTYPE "DIALOG", .isfloating = 1)
|
||||
RULE(.wintype = WTYPE "UTILITY", .isfloating = 1)
|
||||
RULE(.wintype = WTYPE "TOOLBAR", .isfloating = 1)
|
||||
RULE(.wintype = WTYPE "SPLASH", .isfloating = 1)
|
||||
//RULE(.class = "Gimp", .tags = 1 << 4)
|
||||
//RULE(.class = "Firefox", .tags = 1 << 7)
|
||||
RULE(.instance = "spterm", .tags = SPTAG(0), .isfloating = 1)
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Bar rules allow you to configure what is shown where on the bar, as well as
|
||||
* introducing your own bar modules.
|
||||
*
|
||||
* monitor:
|
||||
* -1 show on all monitors
|
||||
* 0 show on monitor 0
|
||||
* 'A' show on active monitor (i.e. focused / selected) (or just -1 for active?)
|
||||
* bar - bar index, 0 is default, 1 is extrabar
|
||||
* alignment - how the module is aligned compared to other modules
|
||||
* widthfunc, drawfunc, clickfunc - providing bar module width, draw and click functions
|
||||
* name - does nothing, intended for visual clue and for logging / debugging
|
||||
*/
|
||||
static const BarRule barrules[] = {
|
||||
/* monitor bar alignment widthfunc drawfunc clickfunc hoverfunc name */
|
||||
{ -1, 0, BAR_ALIGN_LEFT, width_tags, draw_tags, click_tags, hover_tags, "tags" },
|
||||
{ -1, 0, BAR_ALIGN_LEFT, width_ltsymbol, draw_ltsymbol, click_ltsymbol, NULL, "layout" },
|
||||
{ statusmon, 0, BAR_ALIGN_RIGHT, width_status, draw_status, click_status, NULL, "status" },
|
||||
{ -1, 0, BAR_ALIGN_NONE, width_wintitle, draw_wintitle, click_wintitle, NULL, "wintitle" },
|
||||
};
|
||||
|
||||
/* 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 = 0; /* 1 means respect size hints in tiled resizals */
|
||||
static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
|
||||
|
||||
|
||||
|
||||
static const Layout layouts[] = {
|
||||
/* symbol arrange function */
|
||||
{ " master", tile }, /* first entry is default */
|
||||
{ " float", NULL }, /* no layout function means floating behavior */
|
||||
};
|
||||
|
||||
/* key definitions */
|
||||
#define MODKEY Mod4Mask
|
||||
#define TAGKEYS(KEY,TAG) \
|
||||
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
|
||||
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
|
||||
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
|
||||
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
|
||||
|
||||
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
|
||||
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
||||
|
||||
/* commands */
|
||||
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
|
||||
static const char *dmenucmd[] = {
|
||||
"dmenu_run",
|
||||
"-m", dmenumon,
|
||||
"-fn", dmenufont,
|
||||
"-nb", normbgcolor,
|
||||
"-nf", normfgcolor,
|
||||
"-sb", selbgcolor,
|
||||
"-sf", selfgcolor,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *termcmd[] = { "st", NULL };
|
||||
|
||||
///////////////////////////////////////////////KEYBINDS//////////////////////////////////////////////
|
||||
#include <X11/XF86keysym.h>
|
||||
//different commands per OS
|
||||
#ifdef __linux__
|
||||
#define VOL_UP "pamixer --allow-boost -i 10; kill -44 $(pidof dwmblocks)"
|
||||
#define XK_UP "pamixer --allow-boost -i 5; kill -44 $(pidof dwmblocks)"
|
||||
#define VOL_DOWN "pamixer --allow-boost -d 10; kill -44 $(pidof dwmblocks)"
|
||||
#define XK_DOWN "pamixer --allow-boost -d 5; kill -44 $(pidof dwmblocks)"
|
||||
#define VOL_MUTE "pamixer -t; kill -44 $(pidof dwmblocks)"
|
||||
#define VOL_KILL "kill -44 $(pidof dwmblocks)"
|
||||
#elif __OpenBSD__
|
||||
#define VOL_UP "sndioctl output.level=+0.10; pkill -SIGUSR1 dwmblocks"
|
||||
#define XK_UP "sndioctl output.level=+0.05; pkill -SIGUSR1 dwmblocks"
|
||||
#define VOL_DOWN "sndioctl output.level=-0.10; pkill -SIGUSR1 dwmblocks"
|
||||
#define XK_DOWN "sndioctl output.level=-0.05; pkill -SIGUSR1 dwmblocks"
|
||||
#define VOL_MUTE "sndioctl output.mute=!; pkill -SIGUSR1 dwmblocks"
|
||||
#define VOL_KILL "pkill -SIGUSR1 dwmblocks"
|
||||
#elif __FreeBSD__
|
||||
#define VOL_UP "sndioctl output.level=+0.10"
|
||||
#define XK_UP "sndioctl output.level=+0.05"
|
||||
#define VOL_DOWN "sndioctl output.level=-0.10"
|
||||
#define XK_DOWN "sndioctl output.level=-0.05"
|
||||
#define VOL_MUTE "sndioctl output.level=-1"
|
||||
#define VOL_KILL "pkill -SIGUSR2 dwmblocks"
|
||||
#endif
|
||||
|
||||
static Key keys[] = {
|
||||
/*modifierkey function argument */
|
||||
{ MODKEY, XK_r, spawn, {.v = dmenucmd } },
|
||||
{ MODKEY, XK_j, focusstack, {.i = +1 } },
|
||||
{ MODKEY, XK_k, focusstack, {.i = -1 } },
|
||||
{ MODKEY, XK_Down, moveresize, {.v = "0x 25y 0w 0h" } },
|
||||
{ MODKEY, XK_Up, moveresize, {.v = "0x -25y 0w 0h" } },
|
||||
{ MODKEY, XK_Right, moveresize, {.v = "25x 0y 0w 0h" } },
|
||||
{ MODKEY, XK_Left, moveresize, {.v = "-25x 0y 0w 0h" } },
|
||||
{ MODKEY|ShiftMask, XK_Down, moveresize, {.v = "0x 0y 0w 25h" } },
|
||||
{ MODKEY|ShiftMask, XK_Up, moveresize, {.v = "0x 0y 0w -25h" } },
|
||||
{ MODKEY|ShiftMask, XK_Right, moveresize, {.v = "0x 0y 25w 0h" } },
|
||||
{ MODKEY|ShiftMask, XK_Left, moveresize, {.v = "0x 0y -25w 0h" } },
|
||||
{ MODKEY, XK_Tab, view, {0} },
|
||||
{ MODKEY|ShiftMask, XK_F5, xrdb, {.v = NULL } },
|
||||
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
||||
{ MODKEY, XK_space, setlayout, {0} },
|
||||
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
|
||||
{ MODKEY, XK_grave, togglescratch, {.ui = 0 } },
|
||||
{ MODKEY|ControlMask, XK_grave, setscratch, {.ui = 0 } },
|
||||
{ MODKEY|ShiftMask, XK_grave, removescratch, {.ui = 0 } },
|
||||
{ MODKEY, XK_w, togglefullscreen, {0} },
|
||||
{ MODKEY, XK_0, view, {.ui = ~SPTAGMASK } },
|
||||
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~SPTAGMASK } },
|
||||
|
||||
TAGKEYS( XK_1, 0)
|
||||
TAGKEYS( XK_2, 1)
|
||||
TAGKEYS( XK_3, 2)
|
||||
TAGKEYS( XK_4, 3)
|
||||
TAGKEYS( XK_5, 4)
|
||||
TAGKEYS( XK_6, 5)
|
||||
TAGKEYS( XK_7, 6)
|
||||
TAGKEYS( XK_8, 7)
|
||||
TAGKEYS( XK_9, 8)
|
||||
|
||||
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
|
||||
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
|
||||
{ MODKEY|ShiftMask, XK_q,quit, {0} },
|
||||
{ MODKEY|ShiftMask, XK_e,quit, {0} },
|
||||
{ MODKEY, XK_b, togglebar, {0} },
|
||||
{ MODKEY, XK_d, spawn, {.v = dmenucmd } },
|
||||
{ MODKEY, XK_w, togglefullscreen, {0} },
|
||||
{ MODKEY, XK_m, zoom, {0} },
|
||||
{ MODKEY, XK_o, incnmaster, {.i = +1 } },
|
||||
{ MODKEY, XK_Return, spawn, {.v = termcmd } },
|
||||
{ MODKEY|ShiftMask, XK_o, incnmaster, {.i = -1 } },
|
||||
{ MODKEY, XK_s, killclient, {0} },
|
||||
{ MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } },
|
||||
{ MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } },
|
||||
{ MODKEY|ShiftMask, XK_Return, togglescratch, {.ui = 0 } },
|
||||
{ 0, XK_F12, togglescratch, {.ui = 0 } },
|
||||
|
||||
//volume control
|
||||
{ Mod1Mask, XK_equal, spawn, SHCMD(VOL_UP) },
|
||||
{ Mod1Mask, XK_minus, spawn, SHCMD(VOL_DOWN) },
|
||||
{ Mod1Mask, XK_m, spawn, SHCMD(VOL_MUTE) },
|
||||
{ 0, XF86XK_AudioMute, spawn, SHCMD(VOL_MUTE) },
|
||||
{ 0, XF86XK_AudioRaiseVolume, spawn, SHCMD(XK_UP) },
|
||||
{ 0, XF86XK_AudioLowerVolume, spawn, SHCMD(XK_DOWN) },
|
||||
|
||||
{ 0, XK_Print, spawn, SHCMD("screenie")},
|
||||
};
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/* 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} },
|
||||
};
|
||||
|
||||
/* 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 },
|
||||
{ "incrgaps", incrgaps },
|
||||
{ "incrigaps", incrigaps },
|
||||
{ "incrogaps", incrogaps },
|
||||
{ "incrihgaps", incrihgaps },
|
||||
{ "incrivgaps", incrivgaps },
|
||||
{ "incrohgaps", incrohgaps },
|
||||
{ "incrovgaps", incrovgaps },
|
||||
{ "togglegaps", togglegaps },
|
||||
{ "defaultgaps", defaultgaps },
|
||||
{ "setgaps", setgapsex },
|
||||
{ "view", view },
|
||||
{ "viewall", viewallex },
|
||||
{ "viewex", viewex },
|
||||
{ "toggleview", toggleview },
|
||||
{ "toggleviewex", toggleviewex },
|
||||
{ "tag", tag },
|
||||
{ "tagall", tagallex },
|
||||
{ "tagex", tagex },
|
||||
{ "toggletag", toggletag },
|
||||
{ "toggletagex", toggletagex },
|
||||
{ "togglefullscreen", togglefullscreen },
|
||||
{ "fullscreen", fullscreen },
|
||||
{ "togglescratch", togglescratch },
|
||||
{ "killclient", killclient },
|
||||
{ "xrdb", xrdb },
|
||||
{ "quit", quit },
|
||||
{ "setlayout", setlayout },
|
||||
{ "setlayoutex", setlayoutex },
|
||||
};
|
||||
|
55
dwm/config.mk
Normal file
55
dwm/config.mk
Normal file
|
@ -0,0 +1,55 @@
|
|||
# dwm version
|
||||
VERSION = 6.3
|
||||
|
||||
# Customize below to fit your system
|
||||
|
||||
# paths
|
||||
PREFIX = /usr/local
|
||||
MANPREFIX = ${PREFIX}/share/man
|
||||
|
||||
X11INC = /usr/X11R6/include
|
||||
X11LIB = /usr/X11R6/lib
|
||||
|
||||
# Xinerama, comment if you don't want it
|
||||
XINERAMALIBS = -lXinerama
|
||||
XINERAMAFLAGS = -DXINERAMA
|
||||
|
||||
# freetype
|
||||
FREETYPELIBS = -lfontconfig -lXft
|
||||
FREETYPEINC = /usr/include/freetype2
|
||||
|
||||
# Uncomment this for the alpha patch and the winicon patch (BAR_ALPHA_PATCH, BAR_WINICON_PATCH)
|
||||
XRENDER = -lXrender
|
||||
|
||||
# Uncomment this for the mdpcontrol patch / MDPCONTROL_PATCH
|
||||
#MPDCLIENT = -lmpdclient
|
||||
|
||||
# Uncomment for the pango patch / BAR_PANGO_PATCH
|
||||
#PANGOINC = `pkg-config --cflags xft pango pangoxft`
|
||||
#PANGOLIB = `pkg-config --libs xft pango pangoxft`
|
||||
|
||||
# Uncomment for the ipc patch / IPC_PATCH
|
||||
#YAJLLIBS = -lyajl
|
||||
#YAJLINC = -I/usr/include/yajl
|
||||
|
||||
# Uncomment this for the rounded corners patch / ROUNDED_CORNERS_PATCH
|
||||
#XEXTLIB = -lXext
|
||||
|
||||
# Uncomment this for the swallow patch / SWALLOW_PATCH
|
||||
XCBLIBS = -lX11-xcb -lxcb -lxcb-res
|
||||
|
||||
# This is needed for the winicon and tagpreview patches / BAR_WINICON_PATCH / BAR_TAGPREVIEW_PATCH
|
||||
#IMLIB2LIBS = -lImlib2
|
||||
|
||||
# includes and libs
|
||||
INCS = -I${X11INC} -I${FREETYPEINC} ${YAJLINC} ${PANGOINC}
|
||||
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${XRENDER} ${MPDCLIENT} ${XEXTLIB} ${XCBLIBS} ${KVMLIB} ${PANGOLIB} ${YAJLLIBS} ${IMLIB2LIBS}
|
||||
|
||||
# flags
|
||||
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
|
||||
#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
|
||||
CFLAGS = -std=c99 -pedantic -Wall -Wno-unused-function -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
|
||||
LDFLAGS = ${LIBS}
|
||||
|
||||
# compiler and linker
|
||||
CC = cc
|
40
dwm/configure
vendored
Executable file
40
dwm/configure
vendored
Executable file
|
@ -0,0 +1,40 @@
|
|||
#!/bin/sh
|
||||
|
||||
#OS=$(printf 'Linux\nOpenBSD\nFreeBSD\nSolaris' | fzf --layout=reverse --height 40%)
|
||||
OS=$(uname)
|
||||
|
||||
case $OS in
|
||||
Linux) cp -f mkconfig/config.mk.linux config.mk ;;
|
||||
OpenBSD) cp -f mkconfig/config.mk.openbsd config.mk ;;
|
||||
FreeBSD) cp -f mkconfig/config.mk.freebsd config.mk ;;
|
||||
Solaris) cp -f mkconfig/config.mk.solaris config.mk ;;
|
||||
esac
|
||||
|
||||
#sed -i 's/##/#/g' config.mk
|
||||
#sed -i '14 s/^/#/' config.mk
|
||||
#sed -i '15 s/^/#/' config.mk
|
||||
#sed -i '25 s/^/#/' config.mk
|
||||
#sed -i '27 s/^/#/' config.mk
|
||||
#sed -i '29 s/^/#/' config.mk
|
||||
#sed -i '65 s/^/#/' config.mk
|
||||
#sed -i '66 s/^/#/' config.mk
|
||||
#sed -i 's/##/#/g' config.mk
|
||||
#
|
||||
#if [ "$OS" = "Linux" ]; then
|
||||
# true
|
||||
#else if [ "$OS" = "OpenBSD" ]; then
|
||||
# sed -i '27 s/.//' config.mk
|
||||
# sed -i '29 s/.//' config.mk
|
||||
#else if [ "$OS" = "FreeBSD" ]; then
|
||||
# sed -i '14 s/.//' config.mk
|
||||
# sed -i '15 s/.//' config.mk
|
||||
# sed -i '25 s/.//' config.mk
|
||||
#else if [ "$OS" = "Solaris" ]; then
|
||||
# sed -i '65 s/.//' config.mk
|
||||
# sed -i '66 s/.//' config.mk
|
||||
#fi
|
||||
#fi
|
||||
#fi
|
||||
#fi
|
||||
#
|
||||
#sed -i 's/##/#/g' config.mk
|
451
dwm/drw.c
Normal file
451
dwm/drw.c
Normal file
|
@ -0,0 +1,451 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xft/Xft.h>
|
||||
|
||||
#include "drw.h"
|
||||
#include "util.h"
|
||||
|
||||
#define UTF_INVALID 0xFFFD
|
||||
#define UTF_SIZ 4
|
||||
|
||||
static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
|
||||
static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
|
||||
static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
|
||||
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
|
||||
|
||||
|
||||
static long
|
||||
utf8decodebyte(const char c, size_t *i)
|
||||
{
|
||||
for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
|
||||
if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
|
||||
return (unsigned char)c & ~utfmask[*i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t
|
||||
utf8validate(long *u, size_t i)
|
||||
{
|
||||
if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
|
||||
*u = UTF_INVALID;
|
||||
for (i = 1; *u > utfmax[i]; ++i)
|
||||
;
|
||||
return i;
|
||||
}
|
||||
|
||||
static size_t
|
||||
utf8decode(const char *c, long *u, size_t clen)
|
||||
{
|
||||
size_t i, j, len, type;
|
||||
long udecoded;
|
||||
|
||||
*u = UTF_INVALID;
|
||||
if (!clen)
|
||||
return 0;
|
||||
udecoded = utf8decodebyte(c[0], &len);
|
||||
if (!BETWEEN(len, 1, UTF_SIZ))
|
||||
return 1;
|
||||
for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
|
||||
udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
|
||||
if (type)
|
||||
return j;
|
||||
}
|
||||
if (j < len)
|
||||
return 0;
|
||||
*u = udecoded;
|
||||
utf8validate(u, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
Drw *
|
||||
drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap)
|
||||
{
|
||||
Drw *drw = ecalloc(1, sizeof(Drw));
|
||||
|
||||
drw->dpy = dpy;
|
||||
drw->screen = screen;
|
||||
drw->root = root;
|
||||
drw->w = w;
|
||||
drw->h = h;
|
||||
|
||||
drw->visual = visual;
|
||||
drw->depth = depth;
|
||||
drw->cmap = cmap;
|
||||
drw->drawable = XCreatePixmap(dpy, root, w, h, depth);
|
||||
drw->gc = XCreateGC(dpy, drw->drawable, 0, NULL);
|
||||
XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
|
||||
|
||||
return drw;
|
||||
}
|
||||
|
||||
void
|
||||
drw_resize(Drw *drw, unsigned int w, unsigned int h)
|
||||
{
|
||||
if (!drw)
|
||||
return;
|
||||
|
||||
drw->w = w;
|
||||
drw->h = h;
|
||||
if (drw->drawable)
|
||||
XFreePixmap(drw->dpy, drw->drawable);
|
||||
drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, drw->depth);
|
||||
}
|
||||
|
||||
void
|
||||
drw_free(Drw *drw)
|
||||
{
|
||||
XFreePixmap(drw->dpy, drw->drawable);
|
||||
XFreeGC(drw->dpy, drw->gc);
|
||||
drw_fontset_free(drw->fonts);
|
||||
free(drw);
|
||||
}
|
||||
|
||||
/* This function is an implementation detail. Library users should use
|
||||
* drw_fontset_create instead.
|
||||
*/
|
||||
static Fnt *
|
||||
xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
|
||||
{
|
||||
Fnt *font;
|
||||
XftFont *xfont = NULL;
|
||||
FcPattern *pattern = NULL;
|
||||
|
||||
if (fontname) {
|
||||
/* Using the pattern found at font->xfont->pattern does not yield the
|
||||
* same substitution results as using the pattern returned by
|
||||
* FcNameParse; using the latter results in the desired fallback
|
||||
* behaviour whereas the former just results in missing-character
|
||||
* rectangles being drawn, at least with some fonts. */
|
||||
if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
|
||||
fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
|
||||
return NULL;
|
||||
}
|
||||
if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
|
||||
fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
|
||||
XftFontClose(drw->dpy, xfont);
|
||||
return NULL;
|
||||
}
|
||||
} else if (fontpattern) {
|
||||
if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
|
||||
fprintf(stderr, "error, cannot load font from pattern.\n");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
die("no font specified.");
|
||||
}
|
||||
|
||||
/* Do not allow using color fonts. This is a workaround for a BadLength
|
||||
* error from Xft with color glyphs. Modelled on the Xterm workaround. See
|
||||
* https://bugzilla.redhat.com/show_bug.cgi?id=1498269
|
||||
* https://lists.suckless.org/dev/1701/30932.html
|
||||
* https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349
|
||||
* and lots more all over the internet.
|
||||
*/
|
||||
FcBool iscol;
|
||||
if (FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
|
||||
XftFontClose(drw->dpy, xfont);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
font = ecalloc(1, sizeof(Fnt));
|
||||
font->xfont = xfont;
|
||||
font->pattern = pattern;
|
||||
font->h = xfont->ascent + xfont->descent;
|
||||
font->dpy = drw->dpy;
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
static void
|
||||
xfont_free(Fnt *font)
|
||||
{
|
||||
if (!font)
|
||||
return;
|
||||
if (font->pattern)
|
||||
FcPatternDestroy(font->pattern);
|
||||
XftFontClose(font->dpy, font->xfont);
|
||||
free(font);
|
||||
}
|
||||
|
||||
Fnt*
|
||||
drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
|
||||
{
|
||||
Fnt *cur, *ret = NULL;
|
||||
size_t i;
|
||||
|
||||
if (!drw || !fonts)
|
||||
return NULL;
|
||||
|
||||
for (i = 1; i <= fontcount; i++) {
|
||||
if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
|
||||
cur->next = ret;
|
||||
ret = cur;
|
||||
}
|
||||
}
|
||||
return (drw->fonts = ret);
|
||||
}
|
||||
|
||||
void
|
||||
drw_fontset_free(Fnt *font)
|
||||
{
|
||||
if (font) {
|
||||
drw_fontset_free(font->next);
|
||||
xfont_free(font);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
drw_clr_create(
|
||||
Drw *drw,
|
||||
Clr *dest,
|
||||
const char *clrname
|
||||
, unsigned int alpha
|
||||
) {
|
||||
if (!drw || !dest || !clrname)
|
||||
return;
|
||||
|
||||
if (!XftColorAllocName(drw->dpy, drw->visual, drw->cmap,
|
||||
clrname, dest))
|
||||
die("error, cannot allocate color '%s'", clrname);
|
||||
|
||||
dest->pixel = (dest->pixel & 0x00ffffffU) | (alpha << 24);
|
||||
}
|
||||
|
||||
/* Wrapper to create color schemes. The caller has to call free(3) on the
|
||||
* returned color scheme when done using it. */
|
||||
Clr *
|
||||
drw_scm_create(
|
||||
Drw *drw,
|
||||
char *clrnames[],
|
||||
const unsigned int alphas[],
|
||||
size_t clrcount
|
||||
) {
|
||||
size_t i;
|
||||
Clr *ret;
|
||||
|
||||
/* need at least two colors for a scheme */
|
||||
if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < clrcount; i++)
|
||||
drw_clr_create(drw, &ret[i], clrnames[i], alphas[i]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
drw_setfontset(Drw *drw, Fnt *set)
|
||||
{
|
||||
if (drw)
|
||||
drw->fonts = set;
|
||||
}
|
||||
|
||||
void
|
||||
drw_setscheme(Drw *drw, Clr *scm)
|
||||
{
|
||||
if (drw)
|
||||
drw->scheme = scm;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
|
||||
{
|
||||
if (!drw || !drw->scheme)
|
||||
return;
|
||||
XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
|
||||
if (filled)
|
||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
||||
else
|
||||
XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
|
||||
}
|
||||
|
||||
int
|
||||
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert, Bool ignored)
|
||||
{
|
||||
char buf[1024];
|
||||
int ty;
|
||||
unsigned int ew;
|
||||
XftDraw *d = NULL;
|
||||
Fnt *usedfont, *curfont, *nextfont;
|
||||
size_t i, len;
|
||||
int utf8strlen, utf8charlen, render = x || y || w || h;
|
||||
long utf8codepoint = 0;
|
||||
const char *utf8str;
|
||||
FcCharSet *fccharset;
|
||||
FcPattern *fcpattern;
|
||||
FcPattern *match;
|
||||
XftResult result;
|
||||
int charexists = 0;
|
||||
|
||||
if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
|
||||
return 0;
|
||||
|
||||
if (!render) {
|
||||
w = ~w;
|
||||
} else {
|
||||
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
|
||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
||||
d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap);
|
||||
x += lpad;
|
||||
w -= lpad;
|
||||
}
|
||||
|
||||
usedfont = drw->fonts;
|
||||
while (1) {
|
||||
utf8strlen = 0;
|
||||
utf8str = text;
|
||||
nextfont = NULL;
|
||||
while (*text) {
|
||||
utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
|
||||
for (curfont = drw->fonts; curfont; curfont = curfont->next) {
|
||||
charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
|
||||
if (charexists) {
|
||||
if (curfont == usedfont) {
|
||||
utf8strlen += utf8charlen;
|
||||
text += utf8charlen;
|
||||
} else {
|
||||
nextfont = curfont;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!charexists || nextfont)
|
||||
break;
|
||||
else
|
||||
charexists = 0;
|
||||
}
|
||||
|
||||
if (utf8strlen) {
|
||||
drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL);
|
||||
/* shorten text if necessary */
|
||||
for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; drw_font_getexts(usedfont, utf8str, len, &ew, NULL))
|
||||
len--;
|
||||
|
||||
if (len) {
|
||||
memcpy(buf, utf8str, len);
|
||||
buf[len] = '\0';
|
||||
if (len < utf8strlen)
|
||||
for (i = len; i && i > len - 3; buf[--i] = '.')
|
||||
; /* NOP */
|
||||
|
||||
if (render) {
|
||||
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
|
||||
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
|
||||
usedfont->xfont, x, ty, (XftChar8 *)buf, len);
|
||||
}
|
||||
x += ew;
|
||||
w -= ew;
|
||||
}
|
||||
}
|
||||
|
||||
if (!*text) {
|
||||
break;
|
||||
} else if (nextfont) {
|
||||
charexists = 0;
|
||||
usedfont = nextfont;
|
||||
} else {
|
||||
/* Regardless of whether or not a fallback font is found, the
|
||||
* character must be drawn. */
|
||||
charexists = 1;
|
||||
|
||||
fccharset = FcCharSetCreate();
|
||||
FcCharSetAddChar(fccharset, utf8codepoint);
|
||||
|
||||
if (!drw->fonts->pattern) {
|
||||
/* Refer to the comment in xfont_create for more information. */
|
||||
die("the first font in the cache must be loaded from a font string.");
|
||||
}
|
||||
|
||||
fcpattern = FcPatternDuplicate(drw->fonts->pattern);
|
||||
FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset);
|
||||
FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue);
|
||||
FcPatternAddBool(fcpattern, FC_COLOR, FcFalse);
|
||||
|
||||
FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
|
||||
FcDefaultSubstitute(fcpattern);
|
||||
match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
|
||||
|
||||
FcCharSetDestroy(fccharset);
|
||||
FcPatternDestroy(fcpattern);
|
||||
|
||||
if (match) {
|
||||
usedfont = xfont_create(drw, NULL, match);
|
||||
if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
|
||||
for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
|
||||
; /* NOP */
|
||||
curfont->next = usedfont;
|
||||
} else {
|
||||
xfont_free(usedfont);
|
||||
usedfont = drw->fonts;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (d)
|
||||
XftDrawDestroy(d);
|
||||
|
||||
return x + (render ? w : 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
|
||||
{
|
||||
if (!drw)
|
||||
return;
|
||||
|
||||
XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
|
||||
XSync(drw->dpy, False);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
drw_fontset_getwidth(Drw *drw, const char *text, Bool markup)
|
||||
{
|
||||
if (!drw || !drw->fonts || !text)
|
||||
return 0;
|
||||
return drw_text(drw, 0, 0, 0, 0, 0, text, 0, markup);
|
||||
}
|
||||
|
||||
void
|
||||
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
|
||||
{
|
||||
XGlyphInfo ext;
|
||||
|
||||
if (!font || !text)
|
||||
return;
|
||||
|
||||
XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
|
||||
if (w)
|
||||
*w = ext.xOff;
|
||||
if (h)
|
||||
*h = font->h;
|
||||
}
|
||||
|
||||
Cur *
|
||||
drw_cur_create(Drw *drw, int shape)
|
||||
{
|
||||
Cur *cur;
|
||||
|
||||
if (!drw || !(cur = ecalloc(1, sizeof(Cur))))
|
||||
return NULL;
|
||||
|
||||
cur->cursor = XCreateFontCursor(drw->dpy, shape);
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
void
|
||||
drw_cur_free(Drw *drw, Cur *cursor)
|
||||
{
|
||||
if (!cursor)
|
||||
return;
|
||||
|
||||
XFreeCursor(drw->dpy, cursor->cursor);
|
||||
free(cursor);
|
||||
}
|
||||
|
72
dwm/drw.h
Normal file
72
dwm/drw.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
|
||||
typedef struct {
|
||||
Cursor cursor;
|
||||
} Cur;
|
||||
|
||||
typedef struct Fnt {
|
||||
Display *dpy;
|
||||
unsigned int h;
|
||||
XftFont *xfont;
|
||||
FcPattern *pattern;
|
||||
struct Fnt *next;
|
||||
} Fnt;
|
||||
|
||||
enum { ColFg, ColBg, ColBorder, ColFloat, ColCount }; /* Clr scheme index */
|
||||
typedef XftColor Clr;
|
||||
|
||||
typedef struct {
|
||||
unsigned int w, h;
|
||||
Display *dpy;
|
||||
int screen;
|
||||
Window root;
|
||||
Visual *visual;
|
||||
unsigned int depth;
|
||||
Colormap cmap;
|
||||
Drawable drawable;
|
||||
GC gc;
|
||||
Clr *scheme;
|
||||
Fnt *fonts;
|
||||
} Drw;
|
||||
|
||||
/* Drawable abstraction */
|
||||
Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap);
|
||||
void drw_resize(Drw *drw, unsigned int w, unsigned int h);
|
||||
void drw_free(Drw *drw);
|
||||
|
||||
/* Fnt abstraction */
|
||||
Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
|
||||
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
|
||||
void drw_fontset_free(Fnt* set);
|
||||
unsigned int drw_fontset_getwidth(Drw *drw, const char *text, Bool markup);
|
||||
|
||||
/* Colorscheme abstraction */
|
||||
void drw_clr_create(
|
||||
Drw *drw,
|
||||
Clr *dest,
|
||||
const char *clrname
|
||||
, unsigned int alpha
|
||||
);
|
||||
Clr *drw_scm_create(
|
||||
Drw *drw,
|
||||
char *clrnames[],
|
||||
const unsigned int alphas[],
|
||||
size_t clrcount
|
||||
);
|
||||
|
||||
/* Cursor abstraction */
|
||||
Cur *drw_cur_create(Drw *drw, int shape);
|
||||
void drw_cur_free(Drw *drw, Cur *cursor);
|
||||
|
||||
/* Drawing context manipulation */
|
||||
void drw_setfontset(Drw *drw, Fnt *set);
|
||||
void drw_setscheme(Drw *drw, Clr *scm);
|
||||
|
||||
/* Drawing functions */
|
||||
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);
|
||||
int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert, Bool markup);
|
||||
|
||||
/* Map functions */
|
||||
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
|
||||
|
BIN
dwm/drw.o
Normal file
BIN
dwm/drw.o
Normal file
Binary file not shown.
BIN
dwm/dwm
Executable file
BIN
dwm/dwm
Executable file
Binary file not shown.
187
dwm/dwm.1
Normal file
187
dwm/dwm.1
Normal file
|
@ -0,0 +1,187 @@
|
|||
.TH DWM 1 dwm\-VERSION
|
||||
.SH NAME
|
||||
dwm \- dynamic window manager
|
||||
.SH SYNOPSIS
|
||||
.B dwm
|
||||
.RB [ \-v ]
|
||||
.SH DESCRIPTION
|
||||
dwm is a dynamic window manager for X. It manages windows in tiled, monocle
|
||||
and floating layouts. Either layout can be applied dynamically, optimising the
|
||||
environment for the application in use and the task performed.
|
||||
.P
|
||||
In tiled layouts windows are managed in a master and stacking area. The master
|
||||
area on the left contains one window by default, and the stacking area on the
|
||||
right contains all other windows. The number of master area windows can be
|
||||
adjusted from zero to an arbitrary number. In monocle layout all windows are
|
||||
maximised to the screen size. In floating layout windows can be resized and
|
||||
moved freely. Dialog windows are always managed floating, regardless of the
|
||||
layout applied.
|
||||
.P
|
||||
Windows are grouped by tags. Each window can be tagged with one or multiple
|
||||
tags. Selecting certain tags displays all windows with these tags.
|
||||
.P
|
||||
Each screen contains a small status bar which displays all available tags, the
|
||||
layout, the title of the focused window, and the text read from the root window
|
||||
name property, if the screen is focused. A floating window is indicated with an
|
||||
empty square and a maximised floating window is indicated with a filled square
|
||||
before the windows title. The selected tags are indicated with a different
|
||||
color. The tags of the focused window are indicated with a filled square in the
|
||||
top left corner. The tags which are applied to one or more windows are
|
||||
indicated with an empty square in the top left corner.
|
||||
.P
|
||||
dwm draws a small border around windows to indicate the focus state.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-v
|
||||
prints version information to stderr, then exits.
|
||||
.SH USAGE
|
||||
.SS Status bar
|
||||
.TP
|
||||
.B X root window name
|
||||
is read and displayed in the status text area. It can be set with the
|
||||
.BR xsetroot (1)
|
||||
command.
|
||||
.TP
|
||||
.B Button1
|
||||
click on a tag label to display all windows with that tag, click on the layout
|
||||
label toggles between tiled and floating layout.
|
||||
.TP
|
||||
.B Button3
|
||||
click on a tag label adds/removes all windows with that tag to/from the view.
|
||||
.TP
|
||||
.B Super\-Button1
|
||||
click on a tag label applies that tag to the focused window.
|
||||
.TP
|
||||
.B Super\-Button3
|
||||
click on a tag label adds/removes that tag to/from the focused window.
|
||||
.SS Keyboard commands
|
||||
.TP
|
||||
.B Super\-Return
|
||||
Start
|
||||
.BR st(1).
|
||||
.TP
|
||||
.B Super\-Shift\-Return
|
||||
Start or toggle
|
||||
.BR st(1)
|
||||
as a floating (scratchpad) terminal.
|
||||
.TP
|
||||
.B Super\-d
|
||||
Spawn
|
||||
.BR dmenu(1)
|
||||
for launching other programs.
|
||||
.TP
|
||||
.B Super\-f
|
||||
Toggles fullscreen state of focused window.
|
||||
.TP
|
||||
.B Super\-,
|
||||
Focus previous screen, if any.
|
||||
.TP
|
||||
.B Super\-.
|
||||
Focus next screen, if any.
|
||||
.TP
|
||||
.B Super\-Shift\-,
|
||||
Send focused window to previous screen, if any.
|
||||
.TP
|
||||
.B Super\-Shift\-.
|
||||
Send focused window to next screen, if any.
|
||||
.TP
|
||||
.B Super\-b
|
||||
Toggles bar on and off.
|
||||
.TP
|
||||
.B Super\-t
|
||||
Sets tiled layout.
|
||||
.TP
|
||||
.B Super\-m
|
||||
Zooms/cycles focused window to/from master area (tiled layouts only).
|
||||
.TP
|
||||
.B Super\-space
|
||||
Toggles between floating and tiled layout.
|
||||
.TP
|
||||
.B Super\-j
|
||||
Focus next window.
|
||||
.TP
|
||||
.B Super\-k
|
||||
Focus previous window.
|
||||
.TP
|
||||
.B Super\-Shift\-j
|
||||
Move focused stack window downward.
|
||||
.TP
|
||||
.B Super\-Shift\-k
|
||||
Move focused stack window upward.
|
||||
.TP
|
||||
.B Super\-o
|
||||
Increase number of windows in master area.
|
||||
.TP
|
||||
.B Super\-Shift\-o
|
||||
Decrease number of windows in master area.
|
||||
.TP
|
||||
.B Super\-l
|
||||
Increase master area size.
|
||||
.TP
|
||||
.B Super\-h
|
||||
Decrease master area size.
|
||||
.TP
|
||||
.B Super\-m
|
||||
Zooms/cycles focused window to/from master area (tiled layouts only).
|
||||
.TP
|
||||
.B Super\-q
|
||||
Close focused window.
|
||||
.TP
|
||||
.B Super\-Shift\-space
|
||||
Toggle focused window between tiled and floating state.
|
||||
.TP
|
||||
.B Super\-Tab
|
||||
Toggles to the previously selected tags.
|
||||
.TP
|
||||
.B Super\-Shift\-[1..n]
|
||||
Apply nth tag to focused window.
|
||||
.TP
|
||||
.B Super\-Shift\-0
|
||||
Apply all tags to focused window.
|
||||
.TP
|
||||
.B Super\-Control\-Shift\-[1..n]
|
||||
Add/remove nth tag to/from focused window.
|
||||
.TP
|
||||
.B Super\-[1..n]
|
||||
View all windows with nth tag.
|
||||
.TP
|
||||
.B Super\-0
|
||||
View all windows with any tag.
|
||||
.TP
|
||||
.B Super\-Control\-[1..n]
|
||||
Add/remove all windows with nth tag to/from the view.
|
||||
.TP
|
||||
.B Super\-Shift\-q, Super\-Shift\-e
|
||||
Quit dwm.
|
||||
.SS Mouse commands
|
||||
.TP
|
||||
.B Super\-Button1
|
||||
Move focused window while dragging. Tiled windows will be toggled to the floating state.
|
||||
.TP
|
||||
.B Super\-Button2
|
||||
Toggles focused window between floating and tiled state.
|
||||
.TP
|
||||
.B Super\-Button3
|
||||
Resize focused window while dragging. Tiled windows will be toggled to the floating state.
|
||||
.SH CUSTOMIZATION
|
||||
dwm is customized by creating a custom config.h and (re)compiling the source
|
||||
code. This keeps it fast, secure and simple.
|
||||
.SH SEE ALSO
|
||||
.BR dmenu (1),
|
||||
.BR st (1)
|
||||
.SH ISSUES
|
||||
Java applications which use the XToolkit/XAWT backend may draw grey windows
|
||||
only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early
|
||||
JDK 1.6 versions, because it assumes a reparenting window manager. Possible workarounds
|
||||
are using JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or setting the
|
||||
environment variable
|
||||
.BR AWT_TOOLKIT=MToolkit
|
||||
(to use the older Motif backend instead) or running
|
||||
.B xprop -root -f _NET_WM_NAME 32a -set _NET_WM_NAME LG3D
|
||||
or
|
||||
.B wmname LG3D
|
||||
(to pretend that a non-reparenting window manager is running that the
|
||||
XToolkit/XAWT backend can recognize) or when using OpenJDK setting the environment variable
|
||||
.BR _JAVA_AWT_WM_NONREPARENTING=1 .
|
||||
.SH BUGS
|
||||
Send all bug reports with a patch to hackers@suckless.org.
|
BIN
dwm/dwm.o
Normal file
BIN
dwm/dwm.o
Normal file
Binary file not shown.
BIN
dwm/dwm.png
Normal file
BIN
dwm/dwm.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 373 B |
59
dwm/mkconfig/config.mk.freebsd
Normal file
59
dwm/mkconfig/config.mk.freebsd
Normal file
|
@ -0,0 +1,59 @@
|
|||
# dwm version
|
||||
VERSION = 6.3
|
||||
|
||||
# Customize below to fit your system
|
||||
|
||||
# paths
|
||||
PREFIX = /usr/local
|
||||
MANPREFIX = ${PREFIX}/share/man
|
||||
|
||||
X11INC = /usr/X11R6/include
|
||||
X11LIB = /usr/X11R6/lib
|
||||
|
||||
X11INC = /usr/local/include
|
||||
X11LIB = /usr/local/lib
|
||||
|
||||
# Xinerama, comment if you don't want it
|
||||
XINERAMALIBS = -lXinerama
|
||||
XINERAMAFLAGS = -DXINERAMA
|
||||
|
||||
# freetype
|
||||
FREETYPELIBS = -lfontconfig -lXft
|
||||
FREETYPEINC = /usr/include/freetype2
|
||||
FREETYPEINC = /usr/local/include/freetype2
|
||||
|
||||
# Uncomment this for the alpha patch and the winicon patch (BAR_ALPHA_PATCH, BAR_WINICON_PATCH)
|
||||
XRENDER = -lXrender
|
||||
|
||||
# Uncomment this for the mdpcontrol patch / MDPCONTROL_PATCH
|
||||
#MPDCLIENT = -lmpdclient
|
||||
|
||||
# Uncomment for the pango patch / BAR_PANGO_PATCH
|
||||
#PANGOINC = `pkg-config --cflags xft pango pangoxft`
|
||||
#PANGOLIB = `pkg-config --libs xft pango pangoxft`
|
||||
|
||||
# Uncomment for the ipc patch / IPC_PATCH
|
||||
#YAJLLIBS = -lyajl
|
||||
#YAJLINC = -I/usr/include/yajl
|
||||
|
||||
# Uncomment this for the rounded corners patch / ROUNDED_CORNERS_PATCH
|
||||
#XEXTLIB = -lXext
|
||||
|
||||
# Uncomment this for the swallow patch / SWALLOW_PATCH
|
||||
XCBLIBS = -lX11-xcb -lxcb -lxcb-res
|
||||
|
||||
# This is needed for the winicon and tagpreview patches / BAR_WINICON_PATCH / BAR_TAGPREVIEW_PATCH
|
||||
#IMLIB2LIBS = -lImlib2
|
||||
|
||||
# includes and libs
|
||||
INCS = -I${X11INC} -I${FREETYPEINC} ${YAJLINC} ${PANGOINC}
|
||||
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${XRENDER} ${MPDCLIENT} ${XEXTLIB} ${XCBLIBS} ${KVMLIB} ${PANGOLIB} ${YAJLLIBS} ${IMLIB2LIBS}
|
||||
|
||||
# flags
|
||||
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
|
||||
#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
|
||||
CFLAGS = -std=c99 -pedantic -Wall -Wno-unused-function -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
|
||||
LDFLAGS = ${LIBS}
|
||||
|
||||
# compiler and linker
|
||||
CC = cc
|
55
dwm/mkconfig/config.mk.linux
Normal file
55
dwm/mkconfig/config.mk.linux
Normal file
|
@ -0,0 +1,55 @@
|
|||
# dwm version
|
||||
VERSION = 6.3
|
||||
|
||||
# Customize below to fit your system
|
||||
|
||||
# paths
|
||||
PREFIX = /usr/local
|
||||
MANPREFIX = ${PREFIX}/share/man
|
||||
|
||||
X11INC = /usr/X11R6/include
|
||||
X11LIB = /usr/X11R6/lib
|
||||
|
||||
# Xinerama, comment if you don't want it
|
||||
XINERAMALIBS = -lXinerama
|
||||
XINERAMAFLAGS = -DXINERAMA
|
||||
|
||||
# freetype
|
||||
FREETYPELIBS = -lfontconfig -lXft
|
||||
FREETYPEINC = /usr/include/freetype2
|
||||
|
||||
# Uncomment this for the alpha patch and the winicon patch (BAR_ALPHA_PATCH, BAR_WINICON_PATCH)
|
||||
XRENDER = -lXrender
|
||||
|
||||
# Uncomment this for the mdpcontrol patch / MDPCONTROL_PATCH
|
||||
#MPDCLIENT = -lmpdclient
|
||||
|
||||
# Uncomment for the pango patch / BAR_PANGO_PATCH
|
||||
#PANGOINC = `pkg-config --cflags xft pango pangoxft`
|
||||
#PANGOLIB = `pkg-config --libs xft pango pangoxft`
|
||||
|
||||
# Uncomment for the ipc patch / IPC_PATCH
|
||||
#YAJLLIBS = -lyajl
|
||||
#YAJLINC = -I/usr/include/yajl
|
||||
|
||||
# Uncomment this for the rounded corners patch / ROUNDED_CORNERS_PATCH
|
||||
#XEXTLIB = -lXext
|
||||
|
||||
# Uncomment this for the swallow patch / SWALLOW_PATCH
|
||||
XCBLIBS = -lX11-xcb -lxcb -lxcb-res
|
||||
|
||||
# This is needed for the winicon and tagpreview patches / BAR_WINICON_PATCH / BAR_TAGPREVIEW_PATCH
|
||||
#IMLIB2LIBS = -lImlib2
|
||||
|
||||
# includes and libs
|
||||
INCS = -I${X11INC} -I${FREETYPEINC} ${YAJLINC} ${PANGOINC}
|
||||
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${XRENDER} ${MPDCLIENT} ${XEXTLIB} ${XCBLIBS} ${KVMLIB} ${PANGOLIB} ${YAJLLIBS} ${IMLIB2LIBS}
|
||||
|
||||
# flags
|
||||
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
|
||||
#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
|
||||
CFLAGS = -std=c99 -pedantic -Wall -Wno-unused-function -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
|
||||
LDFLAGS = ${LIBS}
|
||||
|
||||
# compiler and linker
|
||||
CC = cc
|
57
dwm/mkconfig/config.mk.openbsd
Normal file
57
dwm/mkconfig/config.mk.openbsd
Normal file
|
@ -0,0 +1,57 @@
|
|||
# dwm version
|
||||
VERSION = 6.3
|
||||
|
||||
# Customize below to fit your system
|
||||
|
||||
# paths
|
||||
PREFIX = /usr/local
|
||||
MANPREFIX = ${PREFIX}/share/man
|
||||
|
||||
X11INC = /usr/X11R6/include
|
||||
X11LIB = /usr/X11R6/lib
|
||||
|
||||
# Xinerama, comment if you don't want it
|
||||
XINERAMALIBS = -lXinerama
|
||||
XINERAMAFLAGS = -DXINERAMA
|
||||
|
||||
# freetype
|
||||
FREETYPELIBS = -lfontconfig -lXft
|
||||
FREETYPEINC = /usr/include/freetype2
|
||||
FREETYPEINC = ${X11INC}/freetype2
|
||||
KVMLIB = -lkvm
|
||||
|
||||
# Uncomment this for the alpha patch and the winicon patch (BAR_ALPHA_PATCH, BAR_WINICON_PATCH)
|
||||
XRENDER = -lXrender
|
||||
|
||||
# Uncomment this for the mdpcontrol patch / MDPCONTROL_PATCH
|
||||
#MPDCLIENT = -lmpdclient
|
||||
|
||||
# Uncomment for the pango patch / BAR_PANGO_PATCH
|
||||
#PANGOINC = `pkg-config --cflags xft pango pangoxft`
|
||||
#PANGOLIB = `pkg-config --libs xft pango pangoxft`
|
||||
|
||||
# Uncomment for the ipc patch / IPC_PATCH
|
||||
#YAJLLIBS = -lyajl
|
||||
#YAJLINC = -I/usr/include/yajl
|
||||
|
||||
# Uncomment this for the rounded corners patch / ROUNDED_CORNERS_PATCH
|
||||
#XEXTLIB = -lXext
|
||||
|
||||
# Uncomment this for the swallow patch / SWALLOW_PATCH
|
||||
XCBLIBS = -lX11-xcb -lxcb -lxcb-res
|
||||
|
||||
# This is needed for the winicon and tagpreview patches / BAR_WINICON_PATCH / BAR_TAGPREVIEW_PATCH
|
||||
#IMLIB2LIBS = -lImlib2
|
||||
|
||||
# includes and libs
|
||||
INCS = -I${X11INC} -I${FREETYPEINC} ${YAJLINC} ${PANGOINC}
|
||||
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${XRENDER} ${MPDCLIENT} ${XEXTLIB} ${XCBLIBS} ${KVMLIB} ${PANGOLIB} ${YAJLLIBS} ${IMLIB2LIBS}
|
||||
|
||||
# flags
|
||||
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
|
||||
#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
|
||||
CFLAGS = -std=c99 -pedantic -Wall -Wno-unused-function -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
|
||||
LDFLAGS = ${LIBS}
|
||||
|
||||
# compiler and linker
|
||||
CC = cc
|
58
dwm/mkconfig/config.mk.solaris
Normal file
58
dwm/mkconfig/config.mk.solaris
Normal file
|
@ -0,0 +1,58 @@
|
|||
# dwm version
|
||||
VERSION = 6.3
|
||||
|
||||
# Customize below to fit your system
|
||||
|
||||
# paths
|
||||
PREFIX = /usr/local
|
||||
MANPREFIX = ${PREFIX}/share/man
|
||||
|
||||
X11INC = /usr/X11R6/include
|
||||
X11LIB = /usr/X11R6/lib
|
||||
|
||||
# Xinerama, comment if you don't want it
|
||||
XINERAMALIBS = -lXinerama
|
||||
XINERAMAFLAGS = -DXINERAMA
|
||||
|
||||
# freetype
|
||||
FREETYPELIBS = -lfontconfig -lXft
|
||||
FREETYPEINC = /usr/include/freetype2
|
||||
|
||||
# Uncomment this for the alpha patch and the winicon patch (BAR_ALPHA_PATCH, BAR_WINICON_PATCH)
|
||||
XRENDER = -lXrender
|
||||
|
||||
# Uncomment this for the mdpcontrol patch / MDPCONTROL_PATCH
|
||||
#MPDCLIENT = -lmpdclient
|
||||
|
||||
# Uncomment for the pango patch / BAR_PANGO_PATCH
|
||||
#PANGOINC = `pkg-config --cflags xft pango pangoxft`
|
||||
#PANGOLIB = `pkg-config --libs xft pango pangoxft`
|
||||
|
||||
# Uncomment for the ipc patch / IPC_PATCH
|
||||
#YAJLLIBS = -lyajl
|
||||
#YAJLINC = -I/usr/include/yajl
|
||||
|
||||
# Uncomment this for the rounded corners patch / ROUNDED_CORNERS_PATCH
|
||||
#XEXTLIB = -lXext
|
||||
|
||||
# Uncomment this for the swallow patch / SWALLOW_PATCH
|
||||
XCBLIBS = -lX11-xcb -lxcb -lxcb-res
|
||||
|
||||
# This is needed for the winicon and tagpreview patches / BAR_WINICON_PATCH / BAR_TAGPREVIEW_PATCH
|
||||
#IMLIB2LIBS = -lImlib2
|
||||
|
||||
# includes and libs
|
||||
INCS = -I${X11INC} -I${FREETYPEINC} ${YAJLINC} ${PANGOINC}
|
||||
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${XRENDER} ${MPDCLIENT} ${XEXTLIB} ${XCBLIBS} ${KVMLIB} ${PANGOLIB} ${YAJLLIBS} ${IMLIB2LIBS}
|
||||
|
||||
# flags
|
||||
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
|
||||
#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
|
||||
CFLAGS = -std=c99 -pedantic -Wall -Wno-unused-function -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
|
||||
LDFLAGS = ${LIBS}
|
||||
|
||||
CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
|
||||
LDFLAGS = ${LIBS}
|
||||
|
||||
# compiler and linker
|
||||
CC = cc
|
20
dwm/patch/attachx.c
Normal file
20
dwm/patch/attachx.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
void
|
||||
attachx(Client *c)
|
||||
{
|
||||
Client *at;
|
||||
|
||||
|
||||
unsigned int n;
|
||||
for (at = c->mon->clients, n = 0; at; at = at->next)
|
||||
if (!at->isfloating && ISVISIBLEONTAG(at, c->tags))
|
||||
if (++n >= c->mon->nmaster)
|
||||
break;
|
||||
|
||||
if (at && c->mon->nmaster) {
|
||||
c->next = at->next;
|
||||
at->next = c;
|
||||
return;
|
||||
}
|
||||
attach(c); // master (default)
|
||||
}
|
||||
|
2
dwm/patch/attachx.h
Normal file
2
dwm/patch/attachx.h
Normal file
|
@ -0,0 +1,2 @@
|
|||
static void attachx(Client *c);
|
||||
|
39
dwm/patch/bar.c
Normal file
39
dwm/patch/bar.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
void
|
||||
barhover(XEvent *e, Bar *bar)
|
||||
{
|
||||
const BarRule *br;
|
||||
Monitor *m = bar->mon;
|
||||
XMotionEvent *ev = &e->xmotion;
|
||||
BarArg barg = { 0, 0, 0, 0 };
|
||||
int r;
|
||||
|
||||
for (r = 0; r < LENGTH(barrules); r++) {
|
||||
br = &barrules[r];
|
||||
if (br->bar != bar->idx || (br->monitor == 'A' && m != selmon) || br->hoverfunc == NULL)
|
||||
continue;
|
||||
if (br->monitor != 'A' && br->monitor != -1 && br->monitor != bar->mon->num)
|
||||
continue;
|
||||
if (bar->x[r] > ev->x || ev->x > bar->x[r] + bar->w[r])
|
||||
continue;
|
||||
|
||||
barg.x = ev->x - bar->x[r];
|
||||
barg.y = ev->y - bar->borderpx;
|
||||
barg.w = bar->w[r];
|
||||
barg.h = bar->bh - 2 * bar->borderpx;
|
||||
|
||||
br->hoverfunc(bar, &barg, ev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Bar *
|
||||
wintobar(Window win)
|
||||
{
|
||||
Monitor *m;
|
||||
Bar *bar;
|
||||
for (m = mons; m; m = m->next)
|
||||
for (bar = m->bar; bar; bar = bar->next)
|
||||
if (bar->win == win)
|
||||
return bar;
|
||||
return NULL;
|
||||
}
|
2
dwm/patch/bar.h
Normal file
2
dwm/patch/bar.h
Normal file
|
@ -0,0 +1,2 @@
|
|||
static void barhover(XEvent *e, Bar *bar);
|
||||
static Bar *wintobar(Window win);
|
43
dwm/patch/bar_alpha.c
Normal file
43
dwm/patch/bar_alpha.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
|
||||
static int useargb = 0;
|
||||
static Visual *visual;
|
||||
static int depth;
|
||||
static Colormap cmap;
|
||||
|
||||
void
|
||||
xinitvisual()
|
||||
{
|
||||
XVisualInfo *infos;
|
||||
XRenderPictFormat *fmt;
|
||||
int nitems;
|
||||
int i;
|
||||
|
||||
XVisualInfo tpl = {
|
||||
.screen = screen,
|
||||
.depth = 32,
|
||||
.class = TrueColor
|
||||
};
|
||||
long masks = VisualScreenMask | VisualDepthMask | VisualClassMask;
|
||||
|
||||
infos = XGetVisualInfo(dpy, masks, &tpl, &nitems);
|
||||
visual = NULL;
|
||||
for (i = 0; i < nitems; i ++) {
|
||||
fmt = XRenderFindVisualFormat(dpy, infos[i].visual);
|
||||
if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
|
||||
visual = infos[i].visual;
|
||||
depth = infos[i].depth;
|
||||
cmap = XCreateColormap(dpy, root, visual, AllocNone);
|
||||
useargb = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
XFree(infos);
|
||||
|
||||
if (!visual) {
|
||||
visual = DefaultVisual(dpy, screen);
|
||||
depth = DefaultDepth(dpy, screen);
|
||||
cmap = DefaultColormap(dpy, screen);
|
||||
}
|
||||
}
|
||||
|
4
dwm/patch/bar_alpha.h
Normal file
4
dwm/patch/bar_alpha.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#define OPAQUE 0xffU
|
||||
|
||||
static void xinitvisual();
|
||||
|
104
dwm/patch/bar_indicators.c
Normal file
104
dwm/patch/bar_indicators.c
Normal file
|
@ -0,0 +1,104 @@
|
|||
/* Indicator properties, you can override these in your config.h if you want. */
|
||||
#ifndef TAGSINDICATOR
|
||||
#define TAGSINDICATOR 1 // 0 = off, 1 = on if >1 client/view tag, 2 = always on
|
||||
#endif
|
||||
#ifndef TAGSPX
|
||||
#define TAGSPX 5 // # pixels for tag grid boxes
|
||||
#endif
|
||||
#ifndef TAGSROWS
|
||||
#define TAGSROWS 3 // # rows in tag grid (9 tags, e.g. 3x3)
|
||||
#endif
|
||||
|
||||
void
|
||||
drawindicator(Monitor *m, Client *c, unsigned int occ, int x, int y, int w, int h, unsigned int tag, int filled, int invert, int type)
|
||||
{
|
||||
int i, boxw, boxs, indn = 0;
|
||||
if (!(occ & 1 << tag) || type == INDICATOR_NONE)
|
||||
return;
|
||||
|
||||
boxs = drw->fonts->h / 9;
|
||||
boxw = drw->fonts->h / 6 + 2;
|
||||
if (filled == -1)
|
||||
filled = m == selmon && m->sel && m->sel->tags & 1 << tag;
|
||||
|
||||
switch (type) {
|
||||
default:
|
||||
case INDICATOR_TOP_LEFT_SQUARE:
|
||||
drw_rect(drw, x + boxs, y + boxs, boxw, boxw, filled, invert);
|
||||
break;
|
||||
case INDICATOR_TOP_LEFT_LARGER_SQUARE:
|
||||
drw_rect(drw, x + boxs + 2, y + boxs+1, boxw+1, boxw+1, filled, invert);
|
||||
break;
|
||||
case INDICATOR_TOP_BAR:
|
||||
drw_rect(drw, x + boxw, y, w - ( 2 * boxw + 1), boxw/2, filled, invert);
|
||||
break;
|
||||
case INDICATOR_TOP_BAR_SLIM:
|
||||
drw_rect(drw, x + boxw, y, w - ( 2 * boxw + 1), 1, 0, invert);
|
||||
break;
|
||||
case INDICATOR_BOTTOM_BAR:
|
||||
drw_rect(drw, x + boxw, y + h - boxw/2, w - ( 2 * boxw + 1), boxw/2, filled, invert);
|
||||
break;
|
||||
case INDICATOR_BOTTOM_BAR_SLIM:
|
||||
drw_rect(drw, x + boxw, y + h - 1, w - ( 2 * boxw + 1), 1, 0, invert);
|
||||
break;
|
||||
case INDICATOR_BOX:
|
||||
drw_rect(drw, x + boxw, y, w - 2 * boxw, h, 0, invert);
|
||||
break;
|
||||
case INDICATOR_BOX_WIDER:
|
||||
drw_rect(drw, x + boxw/2, y, w - boxw, h, 0, invert);
|
||||
break;
|
||||
case INDICATOR_BOX_FULL:
|
||||
drw_rect(drw, x, y, w - 2, h, 0, invert);
|
||||
break;
|
||||
case INDICATOR_CLIENT_DOTS:
|
||||
for (c = m->clients; c; c = c->next) {
|
||||
if (c->tags & (1 << tag)) {
|
||||
drw_rect(drw, x, 1 + (indn * 2), m->sel == c ? 6 : 1, 1, 1, invert);
|
||||
indn++;
|
||||
}
|
||||
if (h <= 1 + (indn * 2)) {
|
||||
indn = 0;
|
||||
x += 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case INDICATOR_RIGHT_TAGS:
|
||||
if (!c)
|
||||
break;
|
||||
for (i = 0; i < NUMTAGS; i++) {
|
||||
drw_rect(drw,
|
||||
( x + w - 2 - ((NUMTAGS / TAGSROWS) * TAGSPX)
|
||||
- (i % (NUMTAGS/TAGSROWS)) + ((i % (NUMTAGS / TAGSROWS)) * TAGSPX)
|
||||
),
|
||||
( y + 2 + ((i / (NUMTAGS/TAGSROWS)) * TAGSPX)
|
||||
- ((i / (NUMTAGS/TAGSROWS)))
|
||||
),
|
||||
TAGSPX, TAGSPX, (c->tags >> i) & 1, 0
|
||||
);
|
||||
}
|
||||
break;
|
||||
case INDICATOR_PLUS_AND_LARGER_SQUARE:
|
||||
boxs += 2;
|
||||
boxw += 2;
|
||||
/* falls through */
|
||||
case INDICATOR_PLUS_AND_SQUARE:
|
||||
drw_rect(drw, x + boxs, y + boxs, boxw % 2 ? boxw : boxw + 1, boxw % 2 ? boxw : boxw + 1, filled, invert);
|
||||
/* falls through */
|
||||
case INDICATOR_PLUS:
|
||||
if (!(boxw % 2))
|
||||
boxw += 1;
|
||||
drw_rect(drw, x + boxs + boxw / 2, y + boxs, 1, boxw, filled, invert); // |
|
||||
drw_rect(drw, x + boxs, y + boxs + boxw / 2, boxw + 1, 1, filled, invert); // ‒
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
drawstateindicator(Monitor *m, Client *c, unsigned int occ, int x, int y, int w, int h, unsigned int tag, int filled, int invert)
|
||||
{
|
||||
if (c->isfloating)
|
||||
drawindicator(m, c, occ, x, y, w, h, tag, filled, invert, floatindicatortype);
|
||||
else
|
||||
drawindicator(m, c, occ, x, y, w, h, tag, filled, invert, tiledindicatortype);
|
||||
}
|
||||
|
21
dwm/patch/bar_indicators.h
Normal file
21
dwm/patch/bar_indicators.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
enum {
|
||||
INDICATOR_NONE,
|
||||
INDICATOR_TOP_LEFT_SQUARE,
|
||||
INDICATOR_TOP_LEFT_LARGER_SQUARE,
|
||||
INDICATOR_TOP_BAR,
|
||||
INDICATOR_TOP_BAR_SLIM,
|
||||
INDICATOR_BOTTOM_BAR,
|
||||
INDICATOR_BOTTOM_BAR_SLIM,
|
||||
INDICATOR_BOX,
|
||||
INDICATOR_BOX_WIDER,
|
||||
INDICATOR_BOX_FULL,
|
||||
INDICATOR_CLIENT_DOTS,
|
||||
INDICATOR_RIGHT_TAGS,
|
||||
INDICATOR_PLUS,
|
||||
INDICATOR_PLUS_AND_SQUARE,
|
||||
INDICATOR_PLUS_AND_LARGER_SQUARE,
|
||||
};
|
||||
|
||||
static void drawindicator(Monitor *m, Client *c, unsigned int occ, int x, int y, int w, int h, unsigned int tag, int filled, int invert, int type);
|
||||
static void drawstateindicator(Monitor *m, Client *c, unsigned int occ, int x, int y, int w, int h, unsigned int tag, int filled, int invert);
|
||||
|
18
dwm/patch/bar_ltsymbol.c
Normal file
18
dwm/patch/bar_ltsymbol.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
int
|
||||
width_ltsymbol(Bar *bar, BarArg *a)
|
||||
{
|
||||
return TEXTW(bar->mon->ltsymbol);
|
||||
}
|
||||
|
||||
int
|
||||
draw_ltsymbol(Bar *bar, BarArg *a)
|
||||
{
|
||||
return drw_text(drw, a->x, a->y, a->w, a->h, lrpad / 2, bar->mon->ltsymbol, 0, False);
|
||||
}
|
||||
|
||||
int
|
||||
click_ltsymbol(Bar *bar, Arg *arg, BarArg *a)
|
||||
{
|
||||
return ClkLtSymbol;
|
||||
}
|
||||
|
4
dwm/patch/bar_ltsymbol.h
Normal file
4
dwm/patch/bar_ltsymbol.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
static int width_ltsymbol(Bar *bar, BarArg *a);
|
||||
static int draw_ltsymbol(Bar *bar, BarArg *a);
|
||||
static int click_ltsymbol(Bar *bar, Arg *arg, BarArg *a);
|
||||
|
20
dwm/patch/bar_status.c
Normal file
20
dwm/patch/bar_status.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
int
|
||||
width_status(Bar *bar, BarArg *a)
|
||||
{
|
||||
return TEXTWM(stext);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
draw_status(Bar *bar, BarArg *a)
|
||||
{
|
||||
return drw_text(drw, a->x, a->y, a->w, a->h, lrpad / 2, stext, 0, True);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
click_status(Bar *bar, Arg *arg, BarArg *a)
|
||||
{
|
||||
return ClkStatusText;
|
||||
}
|
||||
|
4
dwm/patch/bar_status.h
Normal file
4
dwm/patch/bar_status.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
static int width_status(Bar *bar, BarArg *a);
|
||||
static int draw_status(Bar *bar, BarArg *a);
|
||||
static int click_status(Bar *bar, Arg *arg, BarArg *a);
|
||||
|
9
dwm/patch/bar_tagicons.c
Normal file
9
dwm/patch/bar_tagicons.c
Normal file
|
@ -0,0 +1,9 @@
|
|||
char *
|
||||
tagicon(Monitor *m, int tag)
|
||||
{
|
||||
int tagindex = tag + NUMTAGS * m->num;
|
||||
if (tagindex >= LENGTH(tagicons[DEFAULT_TAGS]))
|
||||
tagindex = tagindex % LENGTH(tagicons[DEFAULT_TAGS]);
|
||||
return tagicons[DEFAULT_TAGS][tagindex];
|
||||
}
|
||||
|
8
dwm/patch/bar_tagicons.h
Normal file
8
dwm/patch/bar_tagicons.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
enum {
|
||||
DEFAULT_TAGS,
|
||||
ALTERNATIVE_TAGS,
|
||||
ALT_TAGS_DECORATION,
|
||||
};
|
||||
|
||||
static char * tagicon(Monitor *m, int tag);
|
||||
|
81
dwm/patch/bar_tags.c
Normal file
81
dwm/patch/bar_tags.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
int
|
||||
width_tags(Bar *bar, BarArg *a)
|
||||
{
|
||||
int w, i;
|
||||
Client *c;
|
||||
unsigned int occ = 0;
|
||||
for (c = bar->mon->clients; c; c = c->next)
|
||||
occ |= c->tags == 255 ? 0 : c->tags;
|
||||
|
||||
for (w = 0, i = 0; i < NUMTAGS; i++) {
|
||||
if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i))
|
||||
continue;
|
||||
w += TEXTW(tagicon(bar->mon, i));
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
int
|
||||
draw_tags(Bar *bar, BarArg *a)
|
||||
{
|
||||
int invert;
|
||||
int w, x = a->x;
|
||||
unsigned int i, occ = 0, urg = 0;
|
||||
char *icon;
|
||||
Client *c;
|
||||
Monitor *m = bar->mon;
|
||||
|
||||
for (c = m->clients; c; c = c->next) {
|
||||
occ |= c->tags == 255 ? 0 : c->tags;
|
||||
if (c->isurgent)
|
||||
urg |= c->tags;
|
||||
}
|
||||
for (i = 0; i < NUMTAGS; i++) {
|
||||
/* do not draw vacant tags */
|
||||
if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
|
||||
continue;
|
||||
|
||||
icon = tagicon(bar->mon, i);
|
||||
invert = 0;
|
||||
w = TEXTW(icon);
|
||||
drw_setscheme(drw, scheme[
|
||||
m->tagset[m->seltags] & 1 << i
|
||||
? SchemeTagsSel
|
||||
: urg & 1 << i
|
||||
? SchemeUrg
|
||||
: SchemeTagsNorm
|
||||
]);
|
||||
drw_text(drw, x, a->y, w, a->h, lrpad / 2, icon, invert, False);
|
||||
drawindicator(m, NULL, occ, x, a->y, w, a->h, i, -1, invert, tagindicatortype);
|
||||
x += w;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
click_tags(Bar *bar, Arg *arg, BarArg *a)
|
||||
{
|
||||
int i = 0, x = 0;
|
||||
Client *c;
|
||||
unsigned int occ = 0;
|
||||
for (c = bar->mon->clients; c; c = c->next)
|
||||
occ |= c->tags == 255 ? 0 : c->tags;
|
||||
|
||||
do {
|
||||
if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i))
|
||||
continue;
|
||||
x += TEXTW(tagicon(bar->mon, i));
|
||||
} while (a->x >= x && ++i < NUMTAGS);
|
||||
if (i < NUMTAGS) {
|
||||
arg->ui = 1 << i;
|
||||
}
|
||||
return ClkTagBar;
|
||||
}
|
||||
|
||||
int
|
||||
hover_tags(Bar *bar, BarArg *a, XMotionEvent *ev)
|
||||
{
|
||||
|
||||
return 1;
|
||||
}
|
4
dwm/patch/bar_tags.h
Normal file
4
dwm/patch/bar_tags.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
static int width_tags(Bar *bar, BarArg *a);
|
||||
static int draw_tags(Bar *bar, BarArg *a);
|
||||
static int click_tags(Bar *bar, Arg *arg, BarArg *a);
|
||||
static int hover_tags(Bar *bar, BarArg *a, XMotionEvent *ev);
|
48
dwm/patch/bar_wintitle.c
Normal file
48
dwm/patch/bar_wintitle.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
int
|
||||
width_wintitle(Bar *bar, BarArg *a)
|
||||
{
|
||||
return a->w;
|
||||
}
|
||||
|
||||
int
|
||||
draw_wintitle(Bar *bar, BarArg *a)
|
||||
{
|
||||
int x = a->x + lrpad / 2, w = a->w - lrpad / 2;
|
||||
Monitor *m = bar->mon;
|
||||
Client *c = m->sel;
|
||||
|
||||
if (!c) {
|
||||
drw_setscheme(drw, scheme[SchemeTitleNorm]);
|
||||
drw_rect(drw, x, a->y, w, a->h, 1, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tpad = lrpad / 2;
|
||||
int tx = x;
|
||||
int tw = w;
|
||||
|
||||
drw_setscheme(drw, scheme[m == selmon ? SchemeTitleSel : SchemeTitleNorm]);
|
||||
|
||||
if (w <= TEXTW("A") - lrpad + tpad) // reduce text padding if wintitle is too small
|
||||
tpad = (w - TEXTW("A") + lrpad < 0 ? 0 : (w - TEXTW("A") + lrpad) / 2);
|
||||
|
||||
XSetForeground(drw->dpy, drw->gc, drw->scheme[ColBg].pixel);
|
||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, a->y, w, a->h);
|
||||
|
||||
|
||||
tx += tpad;
|
||||
tw -= lrpad;
|
||||
|
||||
|
||||
drw_text(drw, tx, a->y, tw, a->h, 0, c->name, 0, False);
|
||||
|
||||
drawstateindicator(m, c, 1, x, a->y, w, a->h, 0, 0, c->isfixed);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
click_wintitle(Bar *bar, Arg *arg, BarArg *a)
|
||||
{
|
||||
return ClkWinTitle;
|
||||
}
|
||||
|
4
dwm/patch/bar_wintitle.h
Normal file
4
dwm/patch/bar_wintitle.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
static int width_wintitle(Bar *bar, BarArg *a);
|
||||
static int draw_wintitle(Bar *bar, BarArg *a);
|
||||
static int click_wintitle(Bar *bar, Arg *arg, BarArg *a);
|
||||
|
29
dwm/patch/cool_autostart.c
Normal file
29
dwm/patch/cool_autostart.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/* 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);
|
||||
}
|
||||
}
|
||||
|
2
dwm/patch/cool_autostart.h
Normal file
2
dwm/patch/cool_autostart.h
Normal file
|
@ -0,0 +1,2 @@
|
|||
static void autostart_exec(void);
|
||||
|
130
dwm/patch/dwmc
Executable file
130
dwm/patch/dwmc
Executable file
|
@ -0,0 +1,130 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
signal() {
|
||||
xsetroot -name "fsignal:$*"
|
||||
}
|
||||
|
||||
case $# in
|
||||
1)
|
||||
case $1 in
|
||||
focusurgent) ;&
|
||||
mirrorlayout) ;&
|
||||
mpdcontrol) ;&
|
||||
pushdown) ;&
|
||||
pushup) ;&
|
||||
self_restart) ;&
|
||||
setlayout) ;&
|
||||
setcfact) ;&
|
||||
switchcol) ;&
|
||||
view) ;&
|
||||
viewall) ;&
|
||||
viewtoleft) ;&
|
||||
viewtoright) ;&
|
||||
tagtoleft) ;&
|
||||
tagtoright) ;&
|
||||
tagandviewtoleft) ;&
|
||||
tagandviewtoright) ;&
|
||||
transfer) ;&
|
||||
transferall) ;&
|
||||
togglealttag) ;&
|
||||
togglebar) ;&
|
||||
togglefloating) ;&
|
||||
togglefullscreen) ;&
|
||||
fullscreen) ;&
|
||||
togglefakefullscreen) ;&
|
||||
togglesticky) ;&
|
||||
togglehorizontalmax) ;&
|
||||
toggleverticalmax) ;&
|
||||
togglemax) ;&
|
||||
togglegaps) ;&
|
||||
defaultgaps) ;&
|
||||
unfloatvisible) ;&
|
||||
winview) ;&
|
||||
xrdb) ;&
|
||||
zoom) ;&
|
||||
killclient) ;&
|
||||
quit)
|
||||
signal $1
|
||||
;;
|
||||
*)
|
||||
echo "Unknown command ($1) or missing one argument."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
2)
|
||||
case $1 in
|
||||
cyclelayout) ;&
|
||||
explace) ;&
|
||||
moveplace) ;&
|
||||
mpdchange) ;&
|
||||
setkeymode) ;&
|
||||
switchtag) ;&
|
||||
togglescratch) ;&
|
||||
view)
|
||||
signal $1 ui $2
|
||||
;;
|
||||
viewex) ;&
|
||||
toggleviewex) ;&
|
||||
tagallmon) ;&
|
||||
tagswapmon) ;&
|
||||
tagex) ;&
|
||||
toggletagex) ;&
|
||||
setborderpx) ;&
|
||||
setgaps) ;&
|
||||
setlayoutex) ;&
|
||||
setlayoutaxisex) ;&
|
||||
swapfocus) ;&
|
||||
focusstack) ;&
|
||||
pushstack) ;&
|
||||
inplacerotate) ;&
|
||||
rotatestack) ;&
|
||||
rotatelayoutaxis) ;&
|
||||
incnmaster) ;&
|
||||
incnstack) ;&
|
||||
incrgaps) ;&
|
||||
incrigaps) ;&
|
||||
incrogaps) ;&
|
||||
incrihgaps) ;&
|
||||
incrivgaps) ;&
|
||||
incrohgaps) ;&
|
||||
incrovgaps) ;&
|
||||
movestack) ;&
|
||||
shiftview) ;&
|
||||
shiftviewclients) ;&
|
||||
focusmon) ;&
|
||||
tagmon)
|
||||
signal $1 i $2
|
||||
;;
|
||||
setcfact) ;&
|
||||
setmfact)
|
||||
signal $1 f $2
|
||||
;;
|
||||
*)
|
||||
echo "Unknown command ($1) or too many arguments"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
5)
|
||||
case $1 in
|
||||
setgaps)
|
||||
# Expects "setgaps oh ov ih iv" where -1 means to keep existing values
|
||||
[ $2 = -1 ] && oh=128 || oh=$2
|
||||
[ $3 = -1 ] && ov=128 || ov=$3
|
||||
[ $4 = -1 ] && ih=128 || ih=$4
|
||||
[ $5 = -1 ] && iv=128 || iv=$5
|
||||
signal $1 i $(((oh << 24) + (ov << 16) + (ih << 8) + iv))
|
||||
;;
|
||||
*)
|
||||
echo "Unknown command ($1) or too many arguments"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "Unknown command ($1) or too many arguments"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
85
dwm/patch/dwmc.c
Normal file
85
dwm/patch/dwmc.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
void
|
||||
setlayoutex(const Arg *arg)
|
||||
{
|
||||
setlayout(&((Arg) { .v = &layouts[arg->i] }));
|
||||
}
|
||||
|
||||
void
|
||||
viewex(const Arg *arg)
|
||||
{
|
||||
view(&((Arg) { .ui = 1 << arg->ui }));
|
||||
}
|
||||
|
||||
void
|
||||
viewallex(const Arg *arg)
|
||||
{
|
||||
view(&((Arg){.ui = ~SPTAGMASK}));
|
||||
}
|
||||
|
||||
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
|
||||
tagallex(const Arg *arg)
|
||||
{
|
||||
tag(&((Arg){.ui = ~SPTAGMASK}));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
14
dwm/patch/dwmc.h
Normal file
14
dwm/patch/dwmc.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
typedef struct {
|
||||
const char * sig;
|
||||
void (*func)(const Arg *);
|
||||
} Signal;
|
||||
|
||||
static void setlayoutex(const Arg *arg);
|
||||
static void viewex(const Arg *arg);
|
||||
static void viewallex(const Arg *arg);
|
||||
static void toggleviewex(const Arg *arg);
|
||||
static void tagex(const Arg *arg);
|
||||
static void toggletagex(const Arg *arg);
|
||||
static void tagallex(const Arg *arg);
|
||||
static int fake_signal(void);
|
||||
|
15
dwm/patch/fullscreen.c
Normal file
15
dwm/patch/fullscreen.c
Normal file
|
@ -0,0 +1,15 @@
|
|||
Layout *last_layout;
|
||||
|
||||
void
|
||||
fullscreen(const Arg *arg)
|
||||
{
|
||||
int monocle_pos = 0;
|
||||
if (selmon->showbar || last_layout == NULL) {
|
||||
for (last_layout = (Layout *)layouts; last_layout != selmon->lt[selmon->sellt]; last_layout++);
|
||||
setlayout(&((Arg) { .v = &layouts[monocle_pos] }));
|
||||
} else {
|
||||
setlayout(&((Arg) { .v = last_layout }));
|
||||
}
|
||||
togglebar(arg);
|
||||
}
|
||||
|
2
dwm/patch/fullscreen.h
Normal file
2
dwm/patch/fullscreen.h
Normal file
|
@ -0,0 +1,2 @@
|
|||
static void fullscreen(const Arg *arg);
|
||||
|
27
dwm/patch/include.c
Normal file
27
dwm/patch/include.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
/* Bar functionality */
|
||||
#include "bar_indicators.c"
|
||||
#include "bar_tagicons.c"
|
||||
#include "bar.c"
|
||||
|
||||
#include "bar_alpha.c"
|
||||
#include "bar_ltsymbol.c"
|
||||
#include "bar_status.c"
|
||||
#include "bar_tags.c"
|
||||
#include "bar_wintitle.c"
|
||||
|
||||
/* Other patches */
|
||||
#include "attachx.c"
|
||||
#include "cool_autostart.c"
|
||||
#include "dwmc.c"
|
||||
#include "fullscreen.c"
|
||||
#include "moveresize.c"
|
||||
#include "movestack.c"
|
||||
#include "scratchpad.c"
|
||||
#include "swallow.c"
|
||||
#include "togglefullscreen.c"
|
||||
#include "vanitygaps.c"
|
||||
#include "xrdb.c"
|
||||
/* Layouts */
|
||||
#include "layout_facts.c"
|
||||
#include "layout_tile.c"
|
||||
|
26
dwm/patch/include.h
Normal file
26
dwm/patch/include.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* Bar functionality */
|
||||
#include "bar_indicators.h"
|
||||
#include "bar_tagicons.h"
|
||||
#include "bar.h"
|
||||
|
||||
#include "bar_alpha.h"
|
||||
#include "bar_ltsymbol.h"
|
||||
#include "bar_status.h"
|
||||
#include "bar_tags.h"
|
||||
#include "bar_wintitle.h"
|
||||
|
||||
/* Other patches */
|
||||
#include "attachx.h"
|
||||
#include "cool_autostart.h"
|
||||
#include "dwmc.h"
|
||||
#include "fullscreen.h"
|
||||
#include "moveresize.h"
|
||||
#include "movestack.h"
|
||||
#include "scratchpad.h"
|
||||
#include "swallow.h"
|
||||
#include "togglefullscreen.h"
|
||||
#include "vanitygaps.h"
|
||||
#include "xrdb.h"
|
||||
/* Layouts */
|
||||
#include "layout_tile.h"
|
||||
|
62
dwm/patch/ipc/IPCClient.h
Normal file
62
dwm/patch/ipc/IPCClient.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
#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_
|
||||
|
549
dwm/patch/ipc/dwm-msg.c
Normal file
549
dwm/patch/ipc/dwm-msg.c
Normal file
|
@ -0,0 +1,549 @@
|
|||
#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 (!argc || 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;
|
||||
}
|
||||
|
66
dwm/patch/ipc/yajl_dumps.h
Normal file
66
dwm/patch/ipc/yajl_dumps.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
#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, 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_
|
||||
|
24
dwm/patch/layout_facts.c
Normal file
24
dwm/patch/layout_facts.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
void
|
||||
getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr)
|
||||
{
|
||||
unsigned int n;
|
||||
float mfacts, sfacts;
|
||||
int mtotal = 0, stotal = 0;
|
||||
Client *c;
|
||||
|
||||
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
|
||||
mfacts = MIN(n, m->nmaster);
|
||||
sfacts = n - m->nmaster;
|
||||
|
||||
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
|
||||
if (n < m->nmaster)
|
||||
mtotal += msize / mfacts;
|
||||
else
|
||||
stotal += ssize / sfacts;
|
||||
|
||||
*mf = mfacts; // total factor of master area
|
||||
*sf = sfacts; // total factor of stack area
|
||||
*mr = msize - mtotal; // the remainder (rest) of pixels after an even master split
|
||||
*sr = ssize - stotal; // the remainder (rest) of pixels after an even stack split
|
||||
}
|
||||
|
41
dwm/patch/layout_tile.c
Normal file
41
dwm/patch/layout_tile.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
static void
|
||||
tile(Monitor *m)
|
||||
{
|
||||
unsigned int i, n;
|
||||
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;
|
||||
|
||||
|
||||
int oh, ov, ih, iv;
|
||||
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) * m->mfact;
|
||||
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 / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
|
||||
my += HEIGHT(c) + ih;
|
||||
} else {
|
||||
resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
|
||||
sy += HEIGHT(c) + ih;
|
||||
}
|
||||
}
|
||||
|
2
dwm/patch/layout_tile.h
Normal file
2
dwm/patch/layout_tile.h
Normal file
|
@ -0,0 +1,2 @@
|
|||
static void tile(Monitor *);
|
||||
|
65
dwm/patch/moveresize.c
Normal file
65
dwm/patch/moveresize.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
void
|
||||
moveresize(const Arg *arg) {
|
||||
/* only floating windows can be moved */
|
||||
Client *c;
|
||||
c = selmon->sel;
|
||||
int x, y, w, h, nx, ny, nw, nh, ox, oy, ow, oh;
|
||||
char xAbs, yAbs, wAbs, hAbs;
|
||||
int msx, msy, dx, dy, nmx, nmy;
|
||||
unsigned int dui;
|
||||
Window dummy;
|
||||
|
||||
if (!c || !arg)
|
||||
return;
|
||||
if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
|
||||
return;
|
||||
if (sscanf((char *)arg->v, "%d%c %d%c %d%c %d%c", &x, &xAbs, &y, &yAbs, &w, &wAbs, &h, &hAbs) != 8)
|
||||
return;
|
||||
|
||||
/* compute new window position; prevent window from be positioned outside the current monitor */
|
||||
nw = c->w + w;
|
||||
if (wAbs == 'W')
|
||||
nw = w < selmon->mw - 2 * c->bw ? w : selmon->mw - 2 * c->bw;
|
||||
|
||||
nh = c->h + h;
|
||||
if (hAbs == 'H')
|
||||
nh = h < selmon->mh - 2 * c->bw ? h : selmon->mh - 2 * c->bw;
|
||||
|
||||
nx = c->x + x;
|
||||
if (xAbs == 'X') {
|
||||
if (x < selmon->mx)
|
||||
nx = selmon->mx;
|
||||
else if (x > selmon->mx + selmon->mw)
|
||||
nx = selmon->mx + selmon->mw - nw - 2 * c->bw;
|
||||
else
|
||||
nx = x;
|
||||
}
|
||||
|
||||
ny = c->y + y;
|
||||
if (yAbs == 'Y') {
|
||||
if (y < selmon->my)
|
||||
ny = selmon->my;
|
||||
else if (y > selmon->my + selmon->mh)
|
||||
ny = selmon->my + selmon->mh - nh - 2 * c->bw;
|
||||
else
|
||||
ny = y;
|
||||
}
|
||||
|
||||
ox = c->x;
|
||||
oy = c->y;
|
||||
ow = c->w;
|
||||
oh = c->h;
|
||||
|
||||
XRaiseWindow(dpy, c->win);
|
||||
Bool xqp = XQueryPointer(dpy, root, &dummy, &dummy, &msx, &msy, &dx, &dy, &dui);
|
||||
resize(c, nx, ny, nw, nh, True);
|
||||
|
||||
/* move cursor along with the window to avoid problems caused by the sloppy focus */
|
||||
if (xqp && ox <= msx && (ox + ow) >= msx && oy <= msy && (oy + oh) >= msy)
|
||||
{
|
||||
nmx = c->x - ox + c->w - ow;
|
||||
nmy = c->y - oy + c->h - oh;
|
||||
XWarpPointer(dpy, None, None, 0, 0, 0, 0, nmx, nmy);
|
||||
}
|
||||
}
|
||||
|
2
dwm/patch/moveresize.h
Normal file
2
dwm/patch/moveresize.h
Normal file
|
@ -0,0 +1,2 @@
|
|||
static void moveresize(const Arg *arg);
|
||||
|
51
dwm/patch/movestack.c
Normal file
51
dwm/patch/movestack.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
void
|
||||
movestack(const Arg *arg)
|
||||
{
|
||||
Client *c = NULL, *p = NULL, *pc = NULL, *i;
|
||||
if (arg->i > 0) {
|
||||
if (!selmon->sel)
|
||||
return;
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
2
dwm/patch/movestack.h
Normal file
2
dwm/patch/movestack.h
Normal file
|
@ -0,0 +1,2 @@
|
|||
static void movestack(const Arg *arg);
|
||||
|
77
dwm/patch/scratchpad.c
Normal file
77
dwm/patch/scratchpad.c
Normal file
|
@ -0,0 +1,77 @@
|
|||
void
|
||||
removescratch(const Arg *arg)
|
||||
{
|
||||
Client *c = selmon->sel;
|
||||
if (!c)
|
||||
return;
|
||||
unsigned int scratchtag = SPTAG(arg->ui);
|
||||
c->tags = c->mon->tagset[c->mon->seltags] ^ scratchtag;
|
||||
arrange(c->mon);
|
||||
}
|
||||
|
||||
void
|
||||
setscratch(const Arg *arg)
|
||||
{
|
||||
Client *c = selmon->sel;
|
||||
if (!c)
|
||||
return;
|
||||
unsigned int scratchtag = SPTAG(arg->ui);
|
||||
c->tags = scratchtag;
|
||||
arrange(c->mon);
|
||||
}
|
||||
|
||||
void
|
||||
togglescratch(const Arg *arg)
|
||||
{
|
||||
Client *c = NULL, *next = NULL, *found = NULL;
|
||||
Monitor *mon;
|
||||
unsigned int scratchtag = SPTAG(arg->ui);
|
||||
unsigned int newtagset = 0;
|
||||
int nh = 0, nw = 0;
|
||||
Arg sparg = {.v = scratchpads[arg->ui].cmd};
|
||||
|
||||
for (mon = mons; mon; mon = mon->next) {
|
||||
for (c = mon->clients; c; c = next) {
|
||||
next = c->next;
|
||||
if (!(c->tags & scratchtag))
|
||||
continue;
|
||||
|
||||
found = c;
|
||||
|
||||
if (HIDDEN(c)) {
|
||||
XMapWindow(dpy, c->win);
|
||||
setclientstate(c, NormalState);
|
||||
newtagset = 0;
|
||||
} else
|
||||
newtagset = selmon->tagset[selmon->seltags] ^ scratchtag;
|
||||
|
||||
if (c->mon != selmon) {
|
||||
if (c->mon->tagset[c->mon->seltags] & SPTAGMASK)
|
||||
c->mon->tagset[c->mon->seltags] ^= scratchtag;
|
||||
if (c->w > selmon->ww)
|
||||
nw = selmon->ww - c->bw * 2;
|
||||
if (c->h > selmon->wh)
|
||||
nh = selmon->wh - c->bw * 2;
|
||||
if (nw > 0 || nh > 0)
|
||||
resizeclient(c, c->x, c->y, nw ? nw : c->w, nh ? nh : c->h);
|
||||
sendmon(c, selmon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
if (newtagset) {
|
||||
selmon->tagset[selmon->seltags] = newtagset;
|
||||
focus(NULL);
|
||||
arrange(selmon);
|
||||
}
|
||||
if (ISVISIBLE(found)) {
|
||||
focus(found);
|
||||
restack(selmon);
|
||||
}
|
||||
} else {
|
||||
selmon->tagset[selmon->seltags] |= scratchtag;
|
||||
spawn(&sparg);
|
||||
}
|
||||
}
|
||||
|
9
dwm/patch/scratchpad.h
Normal file
9
dwm/patch/scratchpad.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
typedef struct {
|
||||
const char *name;
|
||||
const void *cmd;
|
||||
} Sp;
|
||||
|
||||
static void removescratch(const Arg *arg);
|
||||
static void setscratch(const Arg *arg);
|
||||
static void togglescratch(const Arg *arg);
|
||||
|
212
dwm/patch/swallow.c
Normal file
212
dwm/patch/swallow.c
Normal file
|
@ -0,0 +1,212 @@
|
|||
#include <X11/Xlib-xcb.h>
|
||||
#include <xcb/res.h>
|
||||
#ifdef __OpenBSD__
|
||||
#include <sys/sysctl.h>
|
||||
#include <kvm.h>
|
||||
#endif /* __OpenBSD__ */
|
||||
|
||||
static int scanner;
|
||||
static xcb_connection_t *xcon;
|
||||
|
||||
int
|
||||
swallow(Client *p, Client *c)
|
||||
{
|
||||
Client *s;
|
||||
XWindowChanges wc;
|
||||
|
||||
if (c->noswallow > 0 || c->isterminal)
|
||||
return 0;
|
||||
if (c->noswallow < 0 && !swallowfloating && c->isfloating)
|
||||
return 0;
|
||||
|
||||
XMapWindow(dpy, c->win);
|
||||
|
||||
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;
|
||||
|
||||
XChangeProperty(dpy, c->win, netatom[NetClientList], XA_WINDOW, 32, PropModeReplace,
|
||||
(unsigned char *) &(p->win), 1);
|
||||
|
||||
updatetitle(p);
|
||||
s = scanner ? c : p;
|
||||
|
||||
wc.border_width = p->bw;
|
||||
XConfigureWindow(dpy, p->win, CWBorderWidth, &wc);
|
||||
XMoveResizeWindow(dpy, p->win, s->x, s->y, s->w, s->h);
|
||||
XSetWindowBorder(dpy, p->win, scheme[SchemeNorm][ColBorder].pixel);
|
||||
|
||||
arrange(p->mon);
|
||||
configure(p);
|
||||
updateclientlist();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
unswallow(Client *c)
|
||||
{
|
||||
XWindowChanges wc;
|
||||
c->win = c->swallowing->win;
|
||||
|
||||
free(c->swallowing);
|
||||
c->swallowing = NULL;
|
||||
|
||||
XDeleteProperty(dpy, c->win, netatom[NetClientList]);
|
||||
|
||||
/* unfullscreen the client */
|
||||
setfullscreen(c, 0);
|
||||
updatetitle(c);
|
||||
arrange(c->mon);
|
||||
XMapWindow(dpy, c->win);
|
||||
|
||||
wc.border_width = c->bw;
|
||||
XConfigureWindow(dpy, c->win, CWBorderWidth, &wc);
|
||||
XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
|
||||
XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
|
||||
|
||||
setclientstate(c, NormalState);
|
||||
focus(NULL);
|
||||
arrange(c->mon);
|
||||
}
|
||||
|
||||
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 (pid_t)0;
|
||||
|
||||
if (fscanf(f, "%*u %*s %*c %u", (unsigned *)&v) != 1)
|
||||
v = (pid_t)0;
|
||||
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;
|
||||
|
||||
c = selmon->sel;
|
||||
if (c && c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid))
|
||||
return c;
|
||||
|
||||
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;
|
||||
}
|
||||
|
8
dwm/patch/swallow.h
Normal file
8
dwm/patch/swallow.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
static pid_t getparentprocess(pid_t p);
|
||||
static int isdescprocess(pid_t p, pid_t c);
|
||||
static int swallow(Client *p, Client *c);
|
||||
static Client *swallowingclient(Window w);
|
||||
static Client *termforwin(const Client *c);
|
||||
static void unswallow(Client *c);
|
||||
static pid_t winpid(Window w);
|
||||
|
10
dwm/patch/togglefullscreen.c
Normal file
10
dwm/patch/togglefullscreen.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
void
|
||||
togglefullscreen(const Arg *arg)
|
||||
{
|
||||
Client *c = selmon->sel;
|
||||
if (!c)
|
||||
return;
|
||||
|
||||
setfullscreen(c, !c->isfullscreen);
|
||||
}
|
||||
|
2
dwm/patch/togglefullscreen.h
Normal file
2
dwm/patch/togglefullscreen.h
Normal file
|
@ -0,0 +1,2 @@
|
|||
static void togglefullscreen(const Arg *arg);
|
||||
|
177
dwm/patch/vanitygaps.c
Normal file
177
dwm/patch/vanitygaps.c
Normal file
|
@ -0,0 +1,177 @@
|
|||
/* Settings */
|
||||
static int enablegaps = 1;
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
/* External function that takes one integer and splits it
|
||||
* into four gap values:
|
||||
* - outer horizontal (oh)
|
||||
* - outer vertical (ov)
|
||||
* - inner horizontal (ih)
|
||||
* - inner vertical (iv)
|
||||
*
|
||||
* Each value is represented as one byte with the uppermost
|
||||
* bit of each byte indicating whether or not to keep the
|
||||
* current value.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* 10000000 10000000 00001111 00001111
|
||||
* | | | |
|
||||
* + keep oh + keep ov + ih 15px + iv 15px
|
||||
*
|
||||
* This gives an int of:
|
||||
* 10000000100000000000111100001111 = 2155876111
|
||||
*
|
||||
* Thus this command should set inner gaps to 15:
|
||||
* xsetroot -name "fsignal:setgaps i 2155876111"
|
||||
*/
|
||||
static void
|
||||
setgapsex(const Arg *arg)
|
||||
{
|
||||
int oh = selmon->gappoh;
|
||||
int ov = selmon->gappov;
|
||||
int ih = selmon->gappih;
|
||||
int iv = selmon->gappiv;
|
||||
|
||||
if (!(arg->i & (1 << 31)))
|
||||
oh = (arg->i & 0x7f000000) >> 24;
|
||||
if (!(arg->i & (1 << 23)))
|
||||
ov = (arg->i & 0x7f0000) >> 16;
|
||||
if (!(arg->i & (1 << 15)))
|
||||
ih = (arg->i & 0x7f00) >> 8;
|
||||
if (!(arg->i & (1 << 7)))
|
||||
iv = (arg->i & 0x7f);
|
||||
|
||||
/* Auto enable gaps if disabled */
|
||||
if (!enablegaps)
|
||||
enablegaps = 1;
|
||||
|
||||
setgaps(oh, ov, ih, iv);
|
||||
}
|
||||
|
||||
static void
|
||||
togglegaps(const Arg *arg)
|
||||
{
|
||||
enablegaps = !enablegaps;
|
||||
|
||||
arrange(NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
defaultgaps(const Arg *arg)
|
||||
{
|
||||
setgaps(gappoh, gappov, gappih, gappiv);
|
||||
}
|
||||
|
||||
static void
|
||||
incrgaps(const Arg *arg)
|
||||
{
|
||||
setgaps(
|
||||
selmon->gappoh + arg->i,
|
||||
selmon->gappov + arg->i,
|
||||
selmon->gappih + arg->i,
|
||||
selmon->gappiv + arg->i
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
incrigaps(const Arg *arg)
|
||||
{
|
||||
setgaps(
|
||||
selmon->gappoh,
|
||||
selmon->gappov,
|
||||
selmon->gappih + arg->i,
|
||||
selmon->gappiv + arg->i
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
incrogaps(const Arg *arg)
|
||||
{
|
||||
setgaps(
|
||||
selmon->gappoh + arg->i,
|
||||
selmon->gappov + arg->i,
|
||||
selmon->gappih,
|
||||
selmon->gappiv
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
incrohgaps(const Arg *arg)
|
||||
{
|
||||
setgaps(
|
||||
selmon->gappoh + arg->i,
|
||||
selmon->gappov,
|
||||
selmon->gappih,
|
||||
selmon->gappiv
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
incrovgaps(const Arg *arg)
|
||||
{
|
||||
setgaps(
|
||||
selmon->gappoh,
|
||||
selmon->gappov + arg->i,
|
||||
selmon->gappih,
|
||||
selmon->gappiv
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
incrihgaps(const Arg *arg)
|
||||
{
|
||||
setgaps(
|
||||
selmon->gappoh,
|
||||
selmon->gappov,
|
||||
selmon->gappih + arg->i,
|
||||
selmon->gappiv
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
incrivgaps(const Arg *arg)
|
||||
{
|
||||
setgaps(
|
||||
selmon->gappoh,
|
||||
selmon->gappov,
|
||||
selmon->gappih,
|
||||
selmon->gappiv + arg->i
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc)
|
||||
{
|
||||
unsigned int n, oe, ie;
|
||||
oe = ie = enablegaps;
|
||||
Client *c;
|
||||
|
||||
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
|
||||
if (n == 1) {
|
||||
oe *= smartgaps_fact; // outer gaps disabled or multiplied 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
|
||||
}
|
||||
|
16
dwm/patch/vanitygaps.h
Normal file
16
dwm/patch/vanitygaps.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
/* 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);
|
||||
|
||||
/* Internals */
|
||||
static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc);
|
||||
static void setgaps(int oh, int ov, int ih, int iv);
|
||||
static void setgapsex(const Arg *arg);
|
||||
|
73
dwm/patch/xrdb.c
Normal file
73
dwm/patch/xrdb.c
Normal file
|
@ -0,0 +1,73 @@
|
|||
void
|
||||
loadxrdb()
|
||||
{
|
||||
Display *display;
|
||||
char * resm;
|
||||
XrmDatabase xrdb;
|
||||
char *type;
|
||||
XrmValue value;
|
||||
|
||||
display = XOpenDisplay(NULL);
|
||||
|
||||
if (display != NULL) {
|
||||
resm = XResourceManagerString(display);
|
||||
|
||||
if (resm != NULL) {
|
||||
xrdb = XrmGetStringDatabase(resm);
|
||||
|
||||
if (xrdb != NULL) {
|
||||
XRDB_LOAD_COLOR("dwm.normfgcolor", normfgcolor);
|
||||
XRDB_LOAD_COLOR("dwm.normbgcolor", normbgcolor);
|
||||
XRDB_LOAD_COLOR("dwm.normbordercolor", normbordercolor);
|
||||
XRDB_LOAD_COLOR("dwm.normfloatcolor", normfloatcolor);
|
||||
XRDB_LOAD_COLOR("dwm.selfgcolor", selfgcolor);
|
||||
XRDB_LOAD_COLOR("dwm.selbgcolor", selbgcolor);
|
||||
XRDB_LOAD_COLOR("dwm.selbordercolor", selbordercolor);
|
||||
XRDB_LOAD_COLOR("dwm.selfloatcolor", selfloatcolor);
|
||||
XRDB_LOAD_COLOR("dwm.titlenormfgcolor", titlenormfgcolor);
|
||||
XRDB_LOAD_COLOR("dwm.titlenormbgcolor", titlenormbgcolor);
|
||||
XRDB_LOAD_COLOR("dwm.titlenormbordercolor", titlenormbordercolor);
|
||||
XRDB_LOAD_COLOR("dwm.titlenormfloatcolor", titlenormfloatcolor);
|
||||
XRDB_LOAD_COLOR("dwm.titleselfgcolor", titleselfgcolor);
|
||||
XRDB_LOAD_COLOR("dwm.titleselbgcolor", titleselbgcolor);
|
||||
XRDB_LOAD_COLOR("dwm.titleselbordercolor", titleselbordercolor);
|
||||
XRDB_LOAD_COLOR("dwm.titleselfloatcolor", titleselfloatcolor);
|
||||
XRDB_LOAD_COLOR("dwm.tagsnormfgcolor", tagsnormfgcolor);
|
||||
XRDB_LOAD_COLOR("dwm.tagsnormbgcolor", tagsnormbgcolor);
|
||||
XRDB_LOAD_COLOR("dwm.tagsnormbordercolor", tagsnormbordercolor);
|
||||
XRDB_LOAD_COLOR("dwm.tagsnormfloatcolor", tagsnormfloatcolor);
|
||||
XRDB_LOAD_COLOR("dwm.tagsselfgcolor", tagsselfgcolor);
|
||||
XRDB_LOAD_COLOR("dwm.tagsselbgcolor", tagsselbgcolor);
|
||||
XRDB_LOAD_COLOR("dwm.tagsselbordercolor", tagsselbordercolor);
|
||||
XRDB_LOAD_COLOR("dwm.tagsselfloatcolor", tagsselfloatcolor);
|
||||
XRDB_LOAD_COLOR("dwm.hidnormfgcolor", hidnormfgcolor);
|
||||
XRDB_LOAD_COLOR("dwm.hidnormbgcolor", hidnormbgcolor);
|
||||
XRDB_LOAD_COLOR("dwm.hidselfgcolor", hidselfgcolor);
|
||||
XRDB_LOAD_COLOR("dwm.hidselbgcolor", hidselbgcolor);
|
||||
XRDB_LOAD_COLOR("dwm.urgfgcolor", urgfgcolor);
|
||||
XRDB_LOAD_COLOR("dwm.urgbgcolor", urgbgcolor);
|
||||
XRDB_LOAD_COLOR("dwm.urgbordercolor", urgbordercolor);
|
||||
XRDB_LOAD_COLOR("dwm.urgfloatcolor", urgfloatcolor);
|
||||
|
||||
XrmDestroyDatabase(xrdb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XCloseDisplay(display);
|
||||
}
|
||||
|
||||
void
|
||||
xrdb(const Arg *arg)
|
||||
{
|
||||
loadxrdb();
|
||||
int i;
|
||||
for (i = 0; i < LENGTH(colors); i++)
|
||||
scheme[i] = drw_scm_create(drw, colors[i],
|
||||
alphas[i],
|
||||
ColCount
|
||||
);
|
||||
focus(NULL);
|
||||
arrange(NULL);
|
||||
}
|
||||
|
22
dwm/patch/xrdb.h
Normal file
22
dwm/patch/xrdb.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include <X11/Xresource.h>
|
||||
|
||||
#define XRDB_LOAD_COLOR(R,V) if (XrmGetResource(xrdb, R, NULL, &type, &value) == True) { \
|
||||
if (value.addr != NULL && strnlen(value.addr, 8) == 7 && value.addr[0] == '#') { \
|
||||
int i = 1; \
|
||||
for (; i <= 6; i++) { \
|
||||
if (value.addr[i] < 48) break; \
|
||||
if (value.addr[i] > 57 && value.addr[i] < 65) break; \
|
||||
if (value.addr[i] > 70 && value.addr[i] < 97) break; \
|
||||
if (value.addr[i] > 102) break; \
|
||||
} \
|
||||
if (i == 7) { \
|
||||
strncpy(V, value.addr, 7); \
|
||||
V[7] = '\0'; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
static void loadxrdb(void);
|
||||
static void xrdb(const Arg *arg);
|
||||
|
||||
|
48
dwm/readme.dwm.txt
Normal file
48
dwm/readme.dwm.txt
Normal file
|
@ -0,0 +1,48 @@
|
|||
dwm - dynamic window manager
|
||||
============================
|
||||
dwm is an extremely fast, small, and dynamic window manager for X.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
In order to build dwm you need the Xlib header files.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
Edit config.mk to match your local setup (dwm is installed into
|
||||
the /usr/local namespace by default).
|
||||
|
||||
Afterwards enter the following command to build and install dwm (if
|
||||
necessary as root):
|
||||
|
||||
make clean install
|
||||
|
||||
|
||||
Running dwm
|
||||
-----------
|
||||
Add the following line to your .xinitrc to start dwm using startx:
|
||||
|
||||
exec dwm
|
||||
|
||||
In order to connect dwm to a specific display, make sure that
|
||||
the DISPLAY environment variable is set correctly, e.g.:
|
||||
|
||||
DISPLAY=foo.bar:1 exec dwm
|
||||
|
||||
(This will start dwm on display :1 of the host foo.bar.)
|
||||
|
||||
In order to display status info in the bar, you can do something
|
||||
like this in your .xinitrc:
|
||||
|
||||
while xsetroot -name "`date` `uptime | sed 's/.*,//'`"
|
||||
do
|
||||
sleep 1
|
||||
done &
|
||||
exec dwm
|
||||
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
The configuration of dwm is done by creating a custom config.h
|
||||
and (re)compiling the source code.
|
43
dwm/transient.c
Normal file
43
dwm/transient.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* cc transient.c -o transient -lX11 */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
int main(void) {
|
||||
Display *d;
|
||||
Window r, f, t = None;
|
||||
XSizeHints h;
|
||||
XEvent e;
|
||||
|
||||
d = XOpenDisplay(NULL);
|
||||
if (!d)
|
||||
exit(1);
|
||||
r = DefaultRootWindow(d);
|
||||
|
||||
f = XCreateSimpleWindow(d, r, 100, 100, 400, 400, 0, 0, 0);
|
||||
h.min_width = h.max_width = h.min_height = h.max_height = 400;
|
||||
h.flags = PMinSize | PMaxSize;
|
||||
XSetWMNormalHints(d, f, &h);
|
||||
XStoreName(d, f, "floating");
|
||||
XMapWindow(d, f);
|
||||
|
||||
XSelectInput(d, f, ExposureMask);
|
||||
while (1) {
|
||||
XNextEvent(d, &e);
|
||||
|
||||
if (t == None) {
|
||||
sleep(5);
|
||||
t = XCreateSimpleWindow(d, r, 50, 50, 100, 100, 0, 0, 0);
|
||||
XSetTransientForHint(d, t, f);
|
||||
XStoreName(d, t, "transient");
|
||||
XMapWindow(d, t);
|
||||
XSelectInput(d, t, ExposureMask);
|
||||
}
|
||||
}
|
||||
|
||||
XCloseDisplay(d);
|
||||
exit(0);
|
||||
}
|
||||
|
36
dwm/util.c
Normal file
36
dwm/util.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
void *
|
||||
ecalloc(size_t nmemb, size_t size)
|
||||
{
|
||||
void *p;
|
||||
|
||||
if (!(p = calloc(nmemb, size)))
|
||||
die("calloc:");
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
die(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
|
||||
fputc(' ', stderr);
|
||||
perror(NULL);
|
||||
} else {
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
19
dwm/util.h
Normal file
19
dwm/util.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||
#endif
|
||||
#ifndef MIN
|
||||
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
||||
#endif
|
||||
#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 *ecalloc(size_t nmemb, size_t size);
|
||||
|
BIN
dwm/util.o
Normal file
BIN
dwm/util.o
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue