Refactored dwm
This commit is contained in:
parent
0aadcb22e7
commit
57cecd9032
9 changed files with 326 additions and 277 deletions
|
@ -63,7 +63,8 @@ static const Rule rules[] = {
|
|||
static const float mfact = 0.50; /* 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 */
|
||||
#include "layouts.c"
|
||||
static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
|
||||
#include "grid.c"
|
||||
static const Layout layouts[] = {
|
||||
/* symbol arrange function */
|
||||
{ "[]=", tile }, /* first entry is default */
|
||||
|
@ -77,13 +78,12 @@ static const Layout layouts[] = {
|
|||
/* |||--- VARIABLES ---||| */
|
||||
/* key definitions */
|
||||
#define MODKEY Mod4Mask
|
||||
#define TAGKEYS(CHAIN,KEY,TAG) \
|
||||
{ MODKEY, CHAIN, KEY, view, {.ui = 1 << TAG} }, \
|
||||
{ MODKEY|ControlMask, CHAIN, KEY, toggleview, {.ui = 1 << TAG} }, \
|
||||
{ MODKEY|ShiftMask, CHAIN, KEY, tag, {.ui = 1 << TAG} }, \
|
||||
{ MODKEY|ControlMask|ShiftMask, CHAIN, KEY, toggletag, {.ui = 1 << TAG} },
|
||||
#define TAGKEYS(KEY,TAG) \
|
||||
{1, {{MODKEY, KEY}}, view, {.ui = 1 << TAG} }, \
|
||||
{1, {{MODKEY|ControlMask, KEY}}, toggleview, {.ui = 1 << TAG} }, \
|
||||
{1, {{MODKEY|ShiftMask, KEY}}, tag, {.ui = 1 << TAG} }, \
|
||||
{1, {{MODKEY|ControlMask|ShiftMask, KEY}}, toggletag, {.ui = 1 << TAG} },
|
||||
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
|
||||
#define CMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
||||
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
||||
/* dmenu */
|
||||
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
|
||||
|
@ -93,160 +93,160 @@ static const char *termcmd[] = { "alacritty", NULL };
|
|||
|
||||
|
||||
/* |||--- KEY BIDINGS ---||| */
|
||||
static Key keys[] = {
|
||||
static Keychord keychords[] = {
|
||||
/* modifier chain key key function argument */
|
||||
|
||||
/* Terminal */
|
||||
{ MODKEY, -1, XK_Return, spawn, {.v = termcmd } },
|
||||
{1, {{MODKEY, XK_Return}}, spawn, {.v = termcmd } },
|
||||
|
||||
/* Top bar toggle */
|
||||
{ MODKEY, -1, XK_b, togglebar, {0} },
|
||||
{1, {{MODKEY|ShiftMask, XK_b}}, togglebar, {0} },
|
||||
|
||||
/* WINDOW TAG AND LAYOUT MANIPULATION */
|
||||
|
||||
/* Tag Bindings */
|
||||
TAGKEYS( -1, XK_1, 0)
|
||||
TAGKEYS( -1, XK_2, 1)
|
||||
TAGKEYS( -1, XK_3, 2)
|
||||
TAGKEYS( -1, XK_4, 3)
|
||||
TAGKEYS( -1, XK_5, 4)
|
||||
TAGKEYS( -1, XK_6, 5)
|
||||
TAGKEYS( -1, XK_7, 6)
|
||||
TAGKEYS( -1, XK_8, 7)
|
||||
TAGKEYS( -1, XK_9, 8)
|
||||
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)
|
||||
/* Close Window */
|
||||
{ MODKEY, -1, XK_q, killclient, {0} },
|
||||
{1, {{MODKEY|ShiftMask, XK_c}}, killclient, {0} },
|
||||
/* Cycle between tags */
|
||||
{ MODKEY|ControlMask, -1, XK_Tab, view, {0} },
|
||||
{1, {{MODKEY|ControlMask, XK_Tab}}, view, {0} },
|
||||
/* Window moving */
|
||||
{ MODKEY|ShiftMask, -1, XK_j, rotatestack, {.i = +1 } },
|
||||
{ MODKEY|ShiftMask, -1, XK_k, rotatestack, {.i = -1 } },
|
||||
{1, {{MODKEY|ShiftMask, XK_j}}, rotatestack, {.i = +1 } },
|
||||
{1, {{MODKEY|ShiftMask, XK_k}}, rotatestack, {.i = -1 } },
|
||||
/* Window focusing */
|
||||
{ MODKEY, -1, XK_j, focusstack, {.i = +1 } },
|
||||
{ MODKEY, -1, XK_k, focusstack, {.i = -1 } },
|
||||
{1, {{MODKEY, XK_j}}, focusstack, {.i = +1 } },
|
||||
{1, {{MODKEY, XK_k}}, focusstack, {.i = -1 } },
|
||||
/* Increase and decrease master windows count */
|
||||
{ MODKEY, -1, XK_i, incnmaster, {.i = +1 } },
|
||||
{ MODKEY, -1, XK_d, incnmaster, {.i = -1 } },
|
||||
{1, {{MODKEY, XK_i}}, incnmaster, {.i = +1 } },
|
||||
{1, {{MODKEY, XK_d}}, incnmaster, {.i = -1 } },
|
||||
/* Increase and decrease master window size */
|
||||
{ MODKEY, -1, XK_h, setmfact, {.f = -0.05} },
|
||||
{ MODKEY, -1, XK_l, setmfact, {.f = +0.05} },
|
||||
{1, {{MODKEY, XK_h}}, setmfact, {.f = -0.05} },
|
||||
{1, {{MODKEY, XK_l}}, setmfact, {.f = +0.05} },
|
||||
/* Move window to master */
|
||||
{ MODKEY|ControlMask, -1, XK_Return, zoom, {0} },
|
||||
{1, {{MODKEY|ControlMask, XK_Return}}, zoom, {0} },
|
||||
/* Cycle between layouts fowards and backwards */
|
||||
{ MODKEY, -1, XK_Tab, cyclelayout, {.i = -1 } },
|
||||
{ MODKEY|ShiftMask, -1, XK_Tab, cyclelayout, {.i = +1 } },
|
||||
/* Cycle between recently used layouts */
|
||||
{ MODKEY, -1, XK_space, setlayout, {0} },
|
||||
{1, {{ MODKEY, XK_Tab}}, cyclelayout, {.i = -1 } },
|
||||
{1, {{ MODKEY|ShiftMask, XK_Tab}}, cyclelayout, {.i = +1 } },
|
||||
/* Switch to tiling layout */
|
||||
{ MODKEY, -1, XK_t, setlayout, {.v = &layouts[0]} },
|
||||
{1, {{MODKEY, XK_t}}, setlayout, {.v = &layouts[0]} },
|
||||
/* Switch to floating layout */
|
||||
{ MODKEY, -1, XK_f, setlayout, {.v = &layouts[1]} },
|
||||
{1, {{MODKEY, XK_f}}, setlayout, {.v = &layouts[1]} },
|
||||
/* Switch to monocle layout */
|
||||
{ MODKEY, -1, XK_m, setlayout, {.v = &layouts[2]} },
|
||||
{1, {{MODKEY, XK_m}}, setlayout, {.v = &layouts[2]} },
|
||||
/* Switch to grid layout */
|
||||
{ MODKEY, -1, XK_g, setlayout, {.v = &layouts[3]} },
|
||||
{1, {{MODKEY, XK_g}}, setlayout, {.v = &layouts[3]} },
|
||||
/* Toggle floating mode */
|
||||
{ MODKEY|ShiftMask, -1, XK_space, togglefloating, {0} },
|
||||
{1, {{MODKEY|ShiftMask, XK_f}}, togglefloating, {0} },
|
||||
/* Toggle fullscreen mode */
|
||||
{1, {{MODKEY, XK_space}}, togglefullscr, {0} },
|
||||
/* View all windows of all tags in the current tag */
|
||||
{ MODKEY, -1, XK_0, view, {.ui = ~0 } },
|
||||
{1, {{MODKEY, XK_0}}, view, {.ui = ~0 } },
|
||||
/* Show focused window on all tags */
|
||||
{ MODKEY|ShiftMask, -1, XK_0, tag, {.ui = ~0 } },
|
||||
{1, {{MODKEY|ShiftMask, XK_0}}, tag, {.ui = ~0 } },
|
||||
/* Focusing between monitors */
|
||||
{ MODKEY, -1, XK_comma, focusmon, {.i = -1 } },
|
||||
{ MODKEY, -1, XK_period, focusmon, {.i = +1 } },
|
||||
{1, {{MODKEY, XK_comma}}, focusmon, {.i = -1 } },
|
||||
{1, {{MODKEY, XK_period}}, focusmon, {.i = +1 } },
|
||||
/* Move focused window between monitors */
|
||||
{ MODKEY|ShiftMask, -1, XK_comma, tagmon, {.i = -1 } },
|
||||
{ MODKEY|ShiftMask, -1, XK_period, tagmon, {.i = +1 } },
|
||||
{1, {{MODKEY|ShiftMask, XK_comma}}, tagmon, {.i = -1 } },
|
||||
{1, {{MODKEY|ShiftMask, XK_period}}, tagmon, {.i = +1 } },
|
||||
|
||||
/* VOLUME CONTROL */
|
||||
/* Toggle mute */
|
||||
{ MODKEY, -1, XK_F1, spawn, CMD("pamixer -t") },
|
||||
{1, {{MODKEY, XK_F1}}, spawn, SHCMD("pamixer -t") },
|
||||
/* Decrease volume by 5% */
|
||||
{ MODKEY, -1, XK_F2, spawn, CMD("pamixer -d 5") },
|
||||
{1, {{MODKEY, XK_F2}}, spawn, SHCMD("pamixer -d 5") },
|
||||
/* Increase volume by 5% */
|
||||
{ MODKEY, -1, XK_F3, spawn, CMD("pamixer -i 5") },
|
||||
{1, {{MODKEY, XK_F3}}, spawn, SHCMD("pamixer -i 5") },
|
||||
/* Toggle microphone mute */
|
||||
{ MODKEY, -1, XK_F4, spawn, CMD("pamixer --default-source -t") },
|
||||
{1, {{MODKEY, XK_F4}}, spawn, SHCMD("pamixer --default-source -t") },
|
||||
|
||||
/* BRIGHTNESS CONTROL */
|
||||
/* Decrease brightness by 5% */
|
||||
{ MODKEY, -1, XK_F5, spawn, CMD("xbacklight -dec 10") },
|
||||
{1, {{MODKEY, XK_F5}}, spawn, SHCMD("xbacklight -dec 10") },
|
||||
/* Increase brightness by 5% */
|
||||
{ MODKEY, -1, XK_F6, spawn, CMD("xbacklight -inc 10") },
|
||||
{1, {{MODKEY, XK_F6}}, spawn, SHCMD("xbacklight -inc 10") },
|
||||
/* Set screen backlight to off */
|
||||
{ MODKEY, -1, XK_F7, spawn, CMD("xbacklight -set 0") },
|
||||
{1, {{MODKEY, XK_F7}}, spawn, SHCMD("xbacklight -set 0") },
|
||||
|
||||
/* KEYBOARD LAYOUTS changed with emacs-style keychords SUPER + k (keyboard) followed by "key" */
|
||||
/* Switch to the spanish keyboard layout */
|
||||
{ MODKEY, XK_k, XK_e, spawn, CMD("setxkbmap -layout es") },
|
||||
{2, {{MODKEY, XK_k}, {0, XK_e}}, spawn, SHCMD("setxkbmap -layout es") },
|
||||
/* Switch to the english keyboard layout */
|
||||
{ MODKEY, XK_k, XK_u, spawn, CMD("setxkbmap -layout us") },
|
||||
{2, {{MODKEY, XK_k}, {0, XK_u}}, spawn, SHCMD("setxkbmap -layout us") },
|
||||
|
||||
/* EMACS PROGRAMS launched with emacs-style heychords SUPER + e (app) followed by "key" */
|
||||
{ MODKEY, XK_e, XK_e, spawn, CMD("emacsclient -c -a 'emacs'") },
|
||||
{ MODKEY, XK_e, XK_b, spawn, CMD("emacsclient -c -a 'emacs' --eval '(ibuffer)'") },
|
||||
{ MODKEY, XK_e, XK_d, spawn, CMD("emacsclient -c -a 'emacs' --eval '(dired nil)'") },
|
||||
{ MODKEY, XK_e, XK_t, spawn, CMD("emacsclient -c -a 'emacs' --eval '(+vterm/here nil)'") },
|
||||
{ MODKEY, XK_e, XK_w, spawn, CMD("emacsclient -c -a 'emacs' --eval '(doom/window-maximize-buffer(eww \"gnu.org\"))'") },
|
||||
{ MODKEY, XK_e, XK_s, spawn, CMD("emacsclient -c -a 'emacs' --eval '(eshell)'") },
|
||||
{2, {{MODKEY, XK_e}, {0, XK_e}}, spawn, SHCMD("emacsclient -c -a 'emacs'") },
|
||||
{2, {{MODKEY, XK_e}, {0, XK_b}}, spawn, SHCMD("emacsclient -c -a 'emacs' --eval '(ibuffer)'") },
|
||||
{2, {{MODKEY, XK_e}, {0, XK_d}}, spawn, SHCMD("emacsclient -c -a 'emacs' --eval '(dired nil)'") },
|
||||
{2, {{MODKEY, XK_e}, {0, XK_v}}, spawn, SHCMD("emacsclient -c -a 'emacs' --eval '(+vterm/here nil)'") },
|
||||
{2, {{MODKEY, XK_e}, {0, XK_s}}, spawn, SHCMD("emacsclient -c -a 'emacs' --eval '(eshell)'") },
|
||||
{2, {{MODKEY, XK_e}, {0, XK_w}}, spawn, SHCMD("emacsclient -c -a 'emacs' --eval '(doom/window-maximize-buffer(eww \"gnu.org\"))'") },
|
||||
|
||||
/* PROGRAMS launched with emacs-style keychords SUPER + a (app) followed by "key" */
|
||||
/* File manager */
|
||||
{ MODKEY, XK_a, XK_f, spawn, CMD("alacritty -t exp --class exp,exp -e $HOME/.config/vifm/scripts/vifmrun") },
|
||||
{2, {{MODKEY, XK_a}, {0, XK_f}}, spawn, SHCMD("alacritty -t exp --class exp,exp -e $HOME/.config/vifm/scripts/vifmrun") },
|
||||
/* Web browser */
|
||||
{ MODKEY, XK_a, XK_w, spawn, CMD("qutebrowser") },
|
||||
{2, {{MODKEY, XK_a}, {0, XK_w}}, spawn, SHCMD("qutebrowser") },
|
||||
/* Chat app */
|
||||
{ MODKEY, XK_a, XK_c, spawn, CMD("alacritty -t cht --class cht,cht -e gomuks") },
|
||||
{2, {{MODKEY, XK_a}, {0, XK_c}}, spawn, SHCMD("alacritty -t cht --class cht,cht -e gomuks") },
|
||||
/* Music player */
|
||||
{ MODKEY, XK_a, XK_m, spawn, CMD("alacritty -t msc --class msc,msc -e cmus") },
|
||||
{2, {{MODKEY, XK_a}, {0, XK_m}}, spawn, SHCMD("alacritty -t msc --class msc,msc -e cmus") },
|
||||
/* Game app */
|
||||
{ MODKEY, XK_a, XK_g, spawn, CMD("retroarch") },
|
||||
{2, {{MODKEY, XK_a}, {0, XK_g}}, spawn, SHCMD("retroarch") },
|
||||
/* Virtual machine manager */
|
||||
{ MODKEY, XK_a, XK_v, spawn, CMD("virt-manager") },
|
||||
{2, {{MODKEY, XK_a}, {0, XK_v}}, spawn, SHCMD("virt-manager") },
|
||||
|
||||
/* MISC PROGRAMS launched with emacs-style keychords SUPER + m (app) followed by "key" */
|
||||
/* System monitor btop */
|
||||
{ MODKEY, XK_s, XK_b, spawn, CMD("alacritty -t misc --class misc,misc -e btop") },
|
||||
{2, {{MODKEY, XK_s}, {0, XK_b}}, spawn, SHCMD("alacritty -t misc --class misc,misc -e btop") },
|
||||
/* System monitor htop */
|
||||
{ MODKEY, XK_s, XK_h, spawn, CMD("alacritty -t misc --class misc,misc -e htop") },
|
||||
{2, {{MODKEY, XK_s}, {0, XK_h}}, spawn, SHCMD("alacritty -t misc --class misc,misc -e htop") },
|
||||
/* Pulse mixer */
|
||||
{ MODKEY, XK_s, XK_p, spawn, CMD("alacritty -t misc --class misc,misc -e pulsemixer") },
|
||||
{2, {{MODKEY, XK_s}, {0, XK_p}}, spawn, SHCMD("alacritty -t misc --class misc,misc -e pulsemixer") },
|
||||
/* Alsa mixer */
|
||||
{ MODKEY, XK_s, XK_m, spawn, CMD("alacritty -t misc --class misc,misc -e alsamixer") },
|
||||
{2, {{MODKEY, XK_s}, {0, XK_m}}, spawn, SHCMD("alacritty -t misc --class misc,misc -e alsamixer") },
|
||||
/* Rss reader */
|
||||
{ MODKEY, XK_s, XK_n, spawn, CMD("alacritty -t misc --class misc,misc -e newsboat") },
|
||||
{2, {{MODKEY, XK_s}, {0, XK_n}}, spawn, SHCMD("alacritty -t misc --class misc,misc -e newsboat") },
|
||||
/* Ytfzf */
|
||||
{ MODKEY, XK_s, XK_y, spawn, CMD("alacritty -t misc --class misc,misc -e ytfzf -flst") },
|
||||
{2, {{MODKEY, XK_s}, {0, XK_y}}, spawn, SHCMD("alacritty -t misc --class misc,misc -e ytfzf -flst") },
|
||||
/* Ani-cli */
|
||||
{ MODKEY, XK_s, XK_a, spawn, CMD("alacritty -t misc --class misc,misc -e ani-cli") },
|
||||
{2, {{MODKEY, XK_s}, {0, XK_a}}, spawn, SHCMD("alacritty -t misc --class misc,misc -e ani-cli") },
|
||||
/* Flix-cli */
|
||||
{ MODKEY, XK_s, XK_f, spawn, CMD("alacritty -t misc --class misc,misc -e flix-cli") },
|
||||
{2, {{MODKEY, XK_s}, {0, XK_f}}, spawn, SHCMD("alacritty -t misc --class misc,misc -e flix-cli") },
|
||||
/* Castero */
|
||||
{ MODKEY, XK_s, XK_c, spawn, CMD("alacritty -t misc --class misc,misc -e castero") },
|
||||
{2, {{MODKEY, XK_s}, {0, XK_c}}, spawn, SHCMD("alacritty -t misc --class misc,misc -e castero") },
|
||||
|
||||
/* DMENU PROMPTS launched with emacs-style keychords SUPER + p (prompt) followed by "key" */
|
||||
/* dmenu */
|
||||
{ MODKEY, XK_p, XK_r, spawn, {.v = dmenucmd } },
|
||||
{2, {{MODKEY, XK_p}, {0, XK_r}}, spawn, {.v = dmenucmd } },
|
||||
/* dmenu_power */
|
||||
{ MODKEY, XK_p, XK_q, spawn, CMD("$HOME/.config/suckless/dmenu/scripts/dmenu_power") },
|
||||
{2, {{MODKEY, XK_p}, {0, XK_q}}, spawn, SHCMD("$HOME/.config/suckless/dmenu/scripts/dmenu_power") },
|
||||
/* dmenu_wifi */
|
||||
{ MODKEY, XK_p, XK_i, spawn, CMD("$HOME/.config/suckless/dmenu/scripts/dmenu_wifi") },
|
||||
{2, {{MODKEY, XK_p}, {0, XK_i}}, spawn, SHCMD("$HOME/.config/suckless/dmenu/scripts/dmenu_wifi") },
|
||||
/* dmenu_wall */
|
||||
{ MODKEY, XK_p, XK_w, spawn, CMD("$HOME/.config/suckless/dmenu/scripts/dmenu_wall") },
|
||||
{2, {{MODKEY, XK_p}, {0, XK_w}}, spawn, SHCMD("$HOME/.config/suckless/dmenu/scripts/dmenu_wall") },
|
||||
/* dmenu_edit */
|
||||
{ MODKEY, XK_p, XK_e, spawn, CMD("$HOME/.config/suckless/dmenu/scripts/dmenu_edit") },
|
||||
{2, {{MODKEY, XK_p}, {0, XK_e}}, spawn, SHCMD("$HOME/.config/suckless/dmenu/scripts/dmenu_edit") },
|
||||
/* dmenu_scrot */
|
||||
{ MODKEY, XK_p, XK_s, spawn, CMD("$HOME/.config/suckless/dmenu/scripts/dmenu_scrot") },
|
||||
{2, {{MODKEY, XK_p}, {0, XK_s}}, spawn, SHCMD("$HOME/.config/suckless/dmenu/scripts/dmenu_scrot") },
|
||||
/* dmenu_drun */
|
||||
{ MODKEY, XK_p, XK_d, spawn, CMD("$HOME/.config/suckless/dmenu/scripts/dmenu_drun") },
|
||||
{2, {{MODKEY, XK_p}, {0, XK_d}}, spawn, SHCMD("$HOME/.config/suckless/dmenu/scripts/dmenu_drun") },
|
||||
/* dmenu_blue */
|
||||
{ MODKEY, XK_p, XK_b, spawn, CMD("$HOME/.config/suckless/dmenu/scripts/dmenu_blue") },
|
||||
{2, {{MODKEY, XK_p}, {0, XK_b}}, spawn, SHCMD("$HOME/.config/suckless/dmenu/scripts/dmenu_blue") },
|
||||
/* dmenu_emoji */
|
||||
{ MODKEY, XK_p, XK_z, spawn, CMD("$HOME/.config/suckless/dmenu/scripts/dmenu_emoji") },
|
||||
{2, {{MODKEY, XK_p}, {0, XK_z}}, spawn, SHCMD("$HOME/.config/suckless/dmenu/scripts/dmenu_emoji") },
|
||||
|
||||
/* DWM BOOTSTRAP */
|
||||
{ MODKEY|ShiftMask|ControlMask, -1, XK_q, quit, {0} },
|
||||
{ MODKEY|ControlMask, -1, XK_r, quit, {1} },
|
||||
{1, {{MODKEY|ControlMask, XK_r}}, quit, {1} },
|
||||
{1, {{MODKEY|ShiftMask, XK_q}}, quit, {0} },
|
||||
};
|
||||
|
||||
/* button definitions */
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* See LICENSE file for copyright and license details. */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -97,6 +98,7 @@ drw_free(Drw *drw)
|
|||
{
|
||||
XFreePixmap(drw->dpy, drw->drawable);
|
||||
XFreeGC(drw->dpy, drw->gc);
|
||||
drw_fontset_free(drw->fonts);
|
||||
free(drw);
|
||||
}
|
||||
|
||||
|
@ -134,6 +136,19 @@ xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
|
|||
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;
|
||||
|
@ -240,12 +255,10 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int
|
|||
int
|
||||
drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert)
|
||||
{
|
||||
char buf[1024];
|
||||
int ty;
|
||||
unsigned int ew;
|
||||
int i, ty, ellipsis_x = 0;
|
||||
unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len;
|
||||
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;
|
||||
|
@ -253,13 +266,17 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
|||
FcPattern *fcpattern;
|
||||
FcPattern *match;
|
||||
XftResult result;
|
||||
int charexists = 0;
|
||||
int charexists = 0, overflow = 0;
|
||||
/* keep track of a couple codepoints for which we have no match. */
|
||||
enum { nomatches_len = 64 };
|
||||
static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches;
|
||||
static unsigned int ellipsis_width = 0;
|
||||
|
||||
if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
|
||||
if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
|
||||
return 0;
|
||||
|
||||
if (!render) {
|
||||
w = ~w;
|
||||
w = invert ? invert : ~invert;
|
||||
} else {
|
||||
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
|
||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
||||
|
@ -269,8 +286,10 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
|||
}
|
||||
|
||||
usedfont = drw->fonts;
|
||||
if (!ellipsis_width && render)
|
||||
ellipsis_width = drw_fontset_getwidth(drw, "...");
|
||||
while (1) {
|
||||
utf8strlen = 0;
|
||||
ew = ellipsis_len = utf8strlen = 0;
|
||||
utf8str = text;
|
||||
nextfont = NULL;
|
||||
while (*text) {
|
||||
|
@ -278,9 +297,27 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
|||
for (curfont = drw->fonts; curfont; curfont = curfont->next) {
|
||||
charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
|
||||
if (charexists) {
|
||||
if (curfont == usedfont) {
|
||||
drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL);
|
||||
if (ew + ellipsis_width <= w) {
|
||||
/* keep track where the ellipsis still fits */
|
||||
ellipsis_x = x + ew;
|
||||
ellipsis_w = w - ew;
|
||||
ellipsis_len = utf8strlen;
|
||||
}
|
||||
|
||||
if (ew + tmpw > w) {
|
||||
overflow = 1;
|
||||
/* called from drw_fontset_getwidth_clamp():
|
||||
* it wants the width AFTER the overflow
|
||||
*/
|
||||
if (!render)
|
||||
x += tmpw;
|
||||
else
|
||||
utf8strlen = ellipsis_len;
|
||||
} else if (curfont == usedfont) {
|
||||
utf8strlen += utf8charlen;
|
||||
text += utf8charlen;
|
||||
ew += tmpw;
|
||||
} else {
|
||||
nextfont = curfont;
|
||||
}
|
||||
|
@ -288,36 +325,25 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
|||
}
|
||||
}
|
||||
|
||||
if (!charexists || nextfont)
|
||||
if (overflow || !charexists || nextfont)
|
||||
break;
|
||||
else
|
||||
charexists = 0;
|
||||
}
|
||||
|
||||
if (utf8strlen) {
|
||||
drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL);
|
||||
/* shorten text if necessary */
|
||||
for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--)
|
||||
drw_font_getexts(usedfont, utf8str, len, &ew, NULL);
|
||||
|
||||
if (len) {
|
||||
memcpy(buf, utf8str, len);
|
||||
buf[len] = '\0';
|
||||
if (len < utf8strlen)
|
||||
for (i = len; i && i > len - 3; buf[--i] = '.')
|
||||
; /* NOP */
|
||||
|
||||
if (render) {
|
||||
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
|
||||
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
|
||||
usedfont->xfont, x, ty, (XftChar8 *)buf, len);
|
||||
}
|
||||
x += ew;
|
||||
w -= ew;
|
||||
if (render) {
|
||||
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
|
||||
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
|
||||
usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen);
|
||||
}
|
||||
x += ew;
|
||||
w -= ew;
|
||||
}
|
||||
if (render && overflow)
|
||||
drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert);
|
||||
|
||||
if (!*text) {
|
||||
if (!*text || overflow) {
|
||||
break;
|
||||
} else if (nextfont) {
|
||||
charexists = 0;
|
||||
|
@ -327,6 +353,12 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
|||
* character must be drawn. */
|
||||
charexists = 1;
|
||||
|
||||
for (i = 0; i < nomatches_len; ++i) {
|
||||
/* avoid calling XftFontMatch if we know we won't find a match */
|
||||
if (utf8codepoint == nomatches.codepoint[i])
|
||||
goto no_match;
|
||||
}
|
||||
|
||||
fccharset = FcCharSetCreate();
|
||||
FcCharSetAddChar(fccharset, utf8codepoint);
|
||||
|
||||
|
@ -355,6 +387,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
|||
curfont->next = usedfont;
|
||||
} else {
|
||||
xfont_free(usedfont);
|
||||
nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint;
|
||||
no_match:
|
||||
usedfont = drw->fonts;
|
||||
}
|
||||
}
|
||||
|
@ -384,6 +418,15 @@ drw_fontset_getwidth(Drw *drw, const char *text)
|
|||
return drw_text(drw, 0, 0, 0, 0, 0, text, 0);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n)
|
||||
{
|
||||
unsigned int tmp = 0;
|
||||
if (drw && drw->fonts && text && n)
|
||||
tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n);
|
||||
return MIN(n, tmp);
|
||||
}
|
||||
|
||||
void
|
||||
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
|
||||
{
|
||||
|
@ -421,4 +464,3 @@ drw_cur_free(Drw *drw, Cur *cursor)
|
|||
XFreeCursor(drw->dpy, cursor->cursor);
|
||||
free(cursor);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/* ____ __ */
|
||||
/* / __ \_________ _/ /_____ */
|
||||
/* / / / / ___/ __ `/ //_/ _ \ */
|
||||
/* / /_/ / / / /_/ / ,< / __/ Clay Gomera (Drake) */
|
||||
/* /_____/_/ \__,_/_/|_|\___/ My custom dwm build */
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
typedef struct {
|
||||
Cursor cursor;
|
||||
|
@ -42,6 +38,7 @@ void drw_free(Drw *drw);
|
|||
Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount);
|
||||
void drw_fontset_free(Fnt* set);
|
||||
unsigned int drw_fontset_getwidth(Drw *drw, const char *text);
|
||||
unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n);
|
||||
void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h);
|
||||
|
||||
/* Colorscheme abstraction */
|
||||
|
@ -62,4 +59,3 @@ int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned in
|
|||
|
||||
/* Map functions */
|
||||
void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
|
||||
|
||||
|
|
|
@ -30,10 +30,18 @@ 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.
|
||||
.P
|
||||
On start, dwm can start additional programs that may be specified in two special
|
||||
shell scripts (see the FILES section below), autostart_blocking.sh and
|
||||
autostart.sh. The former is executed first and dwm will wait for its
|
||||
termination before starting. The latter is executed in the background before
|
||||
dwm enters its handler loop.
|
||||
.P
|
||||
Either of these files may be omitted.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-v
|
||||
prints version information to standard output, then exits.
|
||||
prints version information to stderr, then exits.
|
||||
.SH USAGE
|
||||
.SS Status bar
|
||||
.TP
|
||||
|
@ -122,6 +130,9 @@ Zooms/cycles focused window to/from master area (tiled layouts only).
|
|||
.B Mod1\-Shift\-c
|
||||
Close focused window.
|
||||
.TP
|
||||
.B Mod1\-Shift\-f
|
||||
Toggle fullscreen for focused window.
|
||||
.TP
|
||||
.B Mod1\-Shift\-space
|
||||
Toggle focused window between tiled and floating state.
|
||||
.TP
|
||||
|
@ -161,6 +172,21 @@ Toggles focused window between floating and tiled state.
|
|||
.TP
|
||||
.B Mod1\-Button3
|
||||
Resize focused window while dragging. Tiled windows will be toggled to the floating state.
|
||||
.SH FILES
|
||||
The files containing programs to be started along with dwm are searched for in
|
||||
the following directories:
|
||||
.IP "1. $XDG_DATA_HOME/dwm"
|
||||
.IP "2. $HOME/.local/share/dwm"
|
||||
.IP "3. $HOME/.dwm"
|
||||
.P
|
||||
The first existing directory is scanned for any of the autostart files below.
|
||||
.TP 15
|
||||
autostart.sh
|
||||
This file is started as a shell background process before dwm enters its handler
|
||||
loop.
|
||||
.TP 15
|
||||
autostart_blocking.sh
|
||||
This file is started before any autostart.sh; dwm waits for its termination.
|
||||
.SH CUSTOMIZATION
|
||||
dwm is customized by creating a custom config.h and (re)compiling the source
|
||||
code. This keeps it fast, secure and simple.
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
/* ____ __ */
|
||||
/* / __ \_________ _/ /_____ */
|
||||
/* / / / / ___/ __ `/ //_/ _ \ */
|
||||
/* / /_/ / / / /_/ / ,< / __/ Clay Gomera (Drake) */
|
||||
/* /_____/_/ \__,_/_/|_|\___/ My custom dwm build */
|
||||
/*
|
||||
/* See LICENSE file for copyright and license details.
|
||||
*
|
||||
* dynamic window manager is designed like any other X client as well. It is
|
||||
* driven through handling X events. In contrast to other X clients, a window
|
||||
* manager selects for SubstructureRedirectMask on the root window, to receive
|
||||
|
@ -24,7 +20,6 @@
|
|||
*
|
||||
* To understand everything else, start reading main().
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <signal.h>
|
||||
|
@ -34,6 +29,7 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <X11/cursorfont.h>
|
||||
#include <X11/keysym.h>
|
||||
|
@ -54,8 +50,7 @@
|
|||
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
|
||||
#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
|
||||
* MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
|
||||
#define ISVISIBLEONTAG(C, T) ((C->tags & T))
|
||||
#define ISVISIBLE(C) ISVISIBLEONTAG(C, C->mon->tagset[C->mon->seltags])
|
||||
#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
|
||||
#define LENGTH(X) (sizeof X / sizeof X[0])
|
||||
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
||||
#define WIDTH(X) ((X)->w + 2 * (X)->bw + gappx)
|
||||
|
@ -97,7 +92,7 @@ struct Client {
|
|||
float mina, maxa;
|
||||
int x, y, w, h;
|
||||
int oldx, oldy, oldw, oldh;
|
||||
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
|
||||
int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid;
|
||||
int bw, oldbw;
|
||||
unsigned int tags;
|
||||
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
|
||||
|
@ -109,11 +104,15 @@ struct Client {
|
|||
|
||||
typedef struct {
|
||||
unsigned int mod;
|
||||
KeySym chain;
|
||||
KeySym keysym;
|
||||
} Key;
|
||||
|
||||
typedef struct {
|
||||
unsigned int n;
|
||||
const Key keys[5];
|
||||
void (*func)(const Arg *);
|
||||
const Arg arg;
|
||||
} Key;
|
||||
} Keychord;
|
||||
|
||||
typedef struct {
|
||||
const char *symbol;
|
||||
|
@ -156,7 +155,7 @@ static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interac
|
|||
static void arrange(Monitor *m);
|
||||
static void arrangemon(Monitor *m);
|
||||
static void attach(Client *c);
|
||||
static void attachaside(Client *c);
|
||||
static void attachbottom(Client *c);
|
||||
static void attachstack(Client *c);
|
||||
static void buttonpress(XEvent *e);
|
||||
static void checkotherwm(void);
|
||||
|
@ -182,6 +181,7 @@ static void focus(Client *c);
|
|||
static void focusin(XEvent *e);
|
||||
static void focusmon(const Arg *arg);
|
||||
static void focusstack(const Arg *arg);
|
||||
static Atom getatomprop(Client *c, Atom prop);
|
||||
static int getrootptr(int *x, int *y);
|
||||
static long getstate(Window w);
|
||||
static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
|
||||
|
@ -196,7 +196,6 @@ static void maprequest(XEvent *e);
|
|||
static void monocle(Monitor *m);
|
||||
static void motionnotify(XEvent *e);
|
||||
static void movemouse(const Arg *arg);
|
||||
static Client *nexttagged(Client *c);
|
||||
static Client *nexttiled(Client *c);
|
||||
static void pop(Client *);
|
||||
static void propertynotify(XEvent *e);
|
||||
|
@ -229,6 +228,7 @@ static void tagmon(const Arg *arg);
|
|||
static void tile(Monitor *);
|
||||
static void togglebar(const Arg *arg);
|
||||
static void togglefloating(const Arg *arg);
|
||||
static void togglefullscr(const Arg *arg);
|
||||
static void toggletag(const Arg *arg);
|
||||
static void toggleview(const Arg *arg);
|
||||
static void unfocus(Client *c, int setfocus);
|
||||
|
@ -287,7 +287,7 @@ static Display *dpy;
|
|||
static Drw *drw;
|
||||
static Monitor *mons, *selmon;
|
||||
static Window root, wmcheckwin;
|
||||
static KeySym keychain = -1;
|
||||
unsigned int currentkey = 0;
|
||||
|
||||
static int useargb = 0;
|
||||
static Visual *visual;
|
||||
|
@ -370,6 +370,8 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact)
|
|||
if (*w < bh)
|
||||
*w = bh;
|
||||
if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) {
|
||||
if (!c->hintsvalid)
|
||||
updatesizehints(c);
|
||||
/* see last two sentences in ICCCM 4.1.2.3 */
|
||||
baseismin = c->basew == c->minw && c->baseh == c->minh;
|
||||
if (!baseismin) { /* temporarily remove base dimensions */
|
||||
|
@ -433,17 +435,14 @@ attach(Client *c)
|
|||
}
|
||||
|
||||
void
|
||||
attachaside(Client *c) {
|
||||
Client *at = nexttagged(c);
|
||||
if(!at) {
|
||||
attach(c);
|
||||
return;
|
||||
}
|
||||
c->next = at->next;
|
||||
at->next = c;
|
||||
attachbottom(Client *c)
|
||||
{
|
||||
Client **tc;
|
||||
c->next = NULL;
|
||||
for (tc = &c->mon->clients; *tc; tc = &(*tc)->next);
|
||||
*tc = c;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
attachstack(Client *c)
|
||||
{
|
||||
|
@ -477,7 +476,7 @@ buttonpress(XEvent *e)
|
|||
arg.ui = 1 << i;
|
||||
} else if (ev->x < x + blw)
|
||||
click = ClkLtSymbol;
|
||||
else if (ev->x > selmon->ww - TEXTW(stext))
|
||||
else if (ev->x > selmon->ww - (int)TEXTW(stext))
|
||||
click = ClkStatusText;
|
||||
else
|
||||
click = ClkWinTitle;
|
||||
|
@ -524,6 +523,7 @@ cleanup(void)
|
|||
drw_cur_free(drw, cursor[i]);
|
||||
for (i = 0; i < LENGTH(colors); i++)
|
||||
free(scheme[i]);
|
||||
free(scheme);
|
||||
XDestroyWindow(dpy, wmcheckwin);
|
||||
drw_free(drw);
|
||||
XSync(dpy, False);
|
||||
|
@ -750,17 +750,20 @@ dirtomon(int dir)
|
|||
void
|
||||
drawbar(Monitor *m)
|
||||
{
|
||||
int x, w, sw = 0;
|
||||
int x, w, tw = 0;
|
||||
int boxs = drw->fonts->h / 9;
|
||||
int boxw = drw->fonts->h / 6 + 2;
|
||||
unsigned int i, occ = 0, urg = 0;
|
||||
Client *c;
|
||||
|
||||
if (!m->showbar)
|
||||
return;
|
||||
|
||||
/* draw status first so it can be overdrawn by tags later */
|
||||
if (m == selmon || 1) { /* status is only drawn on selected monitor */
|
||||
if (m == selmon) { /* status is only drawn on selected monitor */
|
||||
drw_setscheme(drw, scheme[SchemeNorm]);
|
||||
sw = TEXTW(stext);
|
||||
drw_text(drw, m->ww - sw, 0, sw, bh, lrpad / 2, stext, 0);
|
||||
tw = TEXTW(stext);
|
||||
drw_text(drw, m->ww - tw, 0, tw, bh, lrpad / 2, stext, 0);
|
||||
}
|
||||
|
||||
for (c = m->clients; c; c = c->next) {
|
||||
|
@ -783,7 +786,7 @@ drawbar(Monitor *m)
|
|||
drw_setscheme(drw, scheme[SchemeNorm]);
|
||||
x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
|
||||
|
||||
if ((w = m->ww - sw - x) > bh) {
|
||||
if ((w = m->ww - tw - x) > bh) {
|
||||
if (m->sel) {
|
||||
drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
|
||||
drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
|
||||
|
@ -911,7 +914,7 @@ focusstack(const Arg *arg)
|
|||
{
|
||||
Client *c = NULL, *i;
|
||||
|
||||
if (!selmon->sel)
|
||||
if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen))
|
||||
return;
|
||||
if (arg->i > 0) {
|
||||
for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next);
|
||||
|
@ -1027,21 +1030,16 @@ grabkeys(void)
|
|||
{
|
||||
updatenumlockmask();
|
||||
{
|
||||
unsigned int i, j;
|
||||
unsigned int i, k;
|
||||
unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
|
||||
KeyCode code;
|
||||
KeyCode chain;
|
||||
|
||||
XUngrabKey(dpy, AnyKey, AnyModifier, root);
|
||||
for (i = 0; i < LENGTH(keys); i++)
|
||||
if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) {
|
||||
if (keys[i].chain != -1 &&
|
||||
((chain = XKeysymToKeycode(dpy, keys[i].chain))))
|
||||
code = chain;
|
||||
for (j = 0; j < LENGTH(modifiers); j++)
|
||||
XGrabKey(dpy, code, keys[i].mod | modifiers[j], root,
|
||||
True, GrabModeAsync, GrabModeAsync);
|
||||
}
|
||||
for (i = 0; i < LENGTH(keychords); i++)
|
||||
if ((code = XKeysymToKeycode(dpy, keychords[i].keys[currentkey].keysym)))
|
||||
for (k = 0; k < LENGTH(modifiers); k++)
|
||||
XGrabKey(dpy, code, keychords[i].keys[currentkey].mod | modifiers[k], root,
|
||||
True, GrabModeAsync, GrabModeAsync);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1067,37 +1065,48 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info)
|
|||
void
|
||||
keypress(XEvent *e)
|
||||
{
|
||||
unsigned int i, j;
|
||||
XEvent event = *e;
|
||||
Keychord *keychord;
|
||||
unsigned int ran = 0;
|
||||
KeySym keysym;
|
||||
XKeyEvent *ev;
|
||||
int current = 0;
|
||||
unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
|
||||
Keychord *newoptions;
|
||||
Keychord *oldoptions = (Keychord *)malloc(sizeof(keychords));
|
||||
|
||||
ev = &e->xkey;
|
||||
keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
|
||||
for (i = 0; i < LENGTH(keys); i++) {
|
||||
if (keysym == keys[i].keysym && keys[i].chain == -1
|
||||
&& CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
|
||||
&& keys[i].func)
|
||||
keys[i].func(&(keys[i].arg));
|
||||
else if (keysym == keys[i].chain && keychain == -1
|
||||
&& CLEANMASK(keys[i].mod) == CLEANMASK(ev->state)
|
||||
&& keys[i].func) {
|
||||
current = 1;
|
||||
keychain = keysym;
|
||||
for (j = 0; j < LENGTH(modifiers); j++)
|
||||
XGrabKey(dpy, AnyKey, 0 | modifiers[j], root,
|
||||
True, GrabModeAsync, GrabModeAsync);
|
||||
} else if (!current && keysym == keys[i].keysym
|
||||
&& keychain != -1
|
||||
&& keys[i].chain == keychain
|
||||
&& keys[i].func)
|
||||
keys[i].func(&(keys[i].arg));
|
||||
}
|
||||
if (!current) {
|
||||
keychain = -1;
|
||||
memcpy(oldoptions, keychords, sizeof(keychords));
|
||||
size_t numoption = 0;
|
||||
while(!ran){
|
||||
ev = &event.xkey;
|
||||
keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
|
||||
newoptions = (Keychord *)malloc(0);
|
||||
numoption = 0;
|
||||
for (keychord = oldoptions; keychord->n != 0 && currentkey < 5; keychord = (Keychord *)((char *)keychord + sizeof(Keychord))){
|
||||
if(keysym == keychord->keys[currentkey].keysym
|
||||
&& CLEANMASK(keychord->keys[currentkey].mod) == CLEANMASK(ev->state)
|
||||
&& keychord->func){
|
||||
if(keychord->n == currentkey +1){
|
||||
keychord->func(&(keychord->arg));
|
||||
ran = 1;
|
||||
}else{
|
||||
numoption++;
|
||||
newoptions = (Keychord *)realloc(newoptions, numoption * sizeof(Keychord));
|
||||
memcpy((char *)newoptions + (numoption -1) * sizeof(Keychord),keychord, sizeof(Keychord));
|
||||
}
|
||||
}
|
||||
}
|
||||
currentkey++;
|
||||
if(numoption == 0)
|
||||
break;
|
||||
grabkeys();
|
||||
while (running && !XNextEvent(dpy, &event) && !ran)
|
||||
if(event.type == KeyPress)
|
||||
break;
|
||||
free(oldoptions);
|
||||
oldoptions = newoptions;
|
||||
}
|
||||
free(newoptions);
|
||||
currentkey = 0;
|
||||
grabkeys();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1164,7 +1173,7 @@ manage(Window w, XWindowAttributes *wa)
|
|||
c->isfloating = c->oldstate = trans != None || c->isfixed;
|
||||
if (c->isfloating)
|
||||
XRaiseWindow(dpy, c->win);
|
||||
attachaside(c);
|
||||
attachbottom(c);
|
||||
attachstack(c);
|
||||
XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
|
||||
(unsigned char *) &(c->win), 1);
|
||||
|
@ -1294,16 +1303,6 @@ movemouse(const Arg *arg)
|
|||
}
|
||||
}
|
||||
|
||||
Client *
|
||||
nexttagged(Client *c) {
|
||||
Client *walked = c->mon->clients;
|
||||
for(;
|
||||
walked && (walked->isfloating || !ISVISIBLEONTAG(walked, c->tags));
|
||||
walked = walked->next
|
||||
);
|
||||
return walked;
|
||||
}
|
||||
|
||||
Client *
|
||||
nexttiled(Client *c)
|
||||
{
|
||||
|
@ -1340,7 +1339,7 @@ propertynotify(XEvent *e)
|
|||
arrange(c->mon);
|
||||
break;
|
||||
case XA_WM_NORMAL_HINTS:
|
||||
updatesizehints(c);
|
||||
c->hintsvalid = 0;
|
||||
break;
|
||||
case XA_WM_HINTS:
|
||||
updatewmhints(c);
|
||||
|
@ -1396,15 +1395,15 @@ resizeclient(Client *c, int x, int y, int w, int h)
|
|||
|
||||
wc.border_width = c->bw;
|
||||
|
||||
/* Get number of clients for the selected monitor */
|
||||
for (n = 0, nbc = nexttiled(selmon->clients); nbc; nbc = nexttiled(nbc->next), n++);
|
||||
/* Get number of clients for the client's monitor */
|
||||
for (n = 0, nbc = nexttiled(c->mon->clients); nbc; nbc = nexttiled(nbc->next), n++);
|
||||
|
||||
/* Do nothing if layout is floating */
|
||||
if (c->isfloating || selmon->lt[selmon->sellt]->arrange == NULL) {
|
||||
if (c->isfloating || c->mon->lt[c->mon->sellt]->arrange == NULL) {
|
||||
gapincr = gapoffset = 0;
|
||||
} else {
|
||||
/* Remove border and gap if layout is monocle or only one client */
|
||||
if (selmon->lt[selmon->sellt]->arrange == monocle || n == 1) {
|
||||
if (c->mon->lt[c->mon->sellt]->arrange == monocle || n == 1) {
|
||||
gapoffset = 0;
|
||||
gapincr = -2 * borderpx;
|
||||
wc.border_width = 0;
|
||||
|
@ -1591,7 +1590,7 @@ sendmon(Client *c, Monitor *m)
|
|||
detachstack(c);
|
||||
c->mon = m;
|
||||
c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
|
||||
attachaside(c);
|
||||
attachbottom(c);
|
||||
attachstack(c);
|
||||
focus(NULL);
|
||||
arrange(NULL);
|
||||
|
@ -1694,7 +1693,7 @@ setmfact(const Arg *arg)
|
|||
if (!arg || !selmon->lt[selmon->sellt]->arrange)
|
||||
return;
|
||||
f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
|
||||
if (f < 0.1 || f > 0.9)
|
||||
if (f < 0.05 || f > 0.95)
|
||||
return;
|
||||
selmon->mfact = f;
|
||||
arrange(selmon);
|
||||
|
@ -1879,12 +1878,14 @@ tile(Monitor *m)
|
|||
for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||
if (i < m->nmaster) {
|
||||
h = (m->wh - my) / (MIN(n, m->nmaster) - i);
|
||||
resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
|
||||
my += HEIGHT(c);
|
||||
resize(c, m->wx, m->wy + my, mw - (2*c->bw) + (n > 1 ? gappx : 0), h - (2*c->bw), 0);
|
||||
if (my + HEIGHT(c) < m->wh)
|
||||
my += HEIGHT(c);
|
||||
} else {
|
||||
h = (m->wh - ty) / (n - i);
|
||||
resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
|
||||
ty += HEIGHT(c);
|
||||
if (ty + HEIGHT(c) < m->wh)
|
||||
ty += HEIGHT(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1911,6 +1912,13 @@ togglefloating(const Arg *arg)
|
|||
arrange(selmon);
|
||||
}
|
||||
|
||||
void
|
||||
togglefullscr(const Arg *arg)
|
||||
{
|
||||
if(selmon->sel)
|
||||
setfullscreen(selmon->sel, !selmon->sel->isfullscreen);
|
||||
}
|
||||
|
||||
void
|
||||
toggletag(const Arg *arg)
|
||||
{
|
||||
|
@ -2062,43 +2070,43 @@ updategeom(void)
|
|||
memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo));
|
||||
XFree(info);
|
||||
nn = j;
|
||||
if (n <= nn) { /* new monitors available */
|
||||
for (i = 0; i < (nn - n); i++) {
|
||||
for (m = mons; m && m->next; m = m->next);
|
||||
if (m)
|
||||
m->next = createmon();
|
||||
else
|
||||
mons = createmon();
|
||||
|
||||
/* new monitors if nn > n */
|
||||
for (i = n; i < nn; i++) {
|
||||
for (m = mons; m && m->next; m = m->next);
|
||||
if (m)
|
||||
m->next = createmon();
|
||||
else
|
||||
mons = createmon();
|
||||
}
|
||||
for (i = 0, m = mons; i < nn && m; m = m->next, i++)
|
||||
if (i >= n
|
||||
|| unique[i].x_org != m->mx || unique[i].y_org != m->my
|
||||
|| unique[i].width != m->mw || unique[i].height != m->mh)
|
||||
{
|
||||
dirty = 1;
|
||||
m->num = i;
|
||||
m->mx = m->wx = unique[i].x_org;
|
||||
m->my = m->wy = unique[i].y_org;
|
||||
m->mw = m->ww = unique[i].width;
|
||||
m->mh = m->wh = unique[i].height;
|
||||
updatebarpos(m);
|
||||
}
|
||||
for (i = 0, m = mons; i < nn && m; m = m->next, i++)
|
||||
if (i >= n
|
||||
|| unique[i].x_org != m->mx || unique[i].y_org != m->my
|
||||
|| unique[i].width != m->mw || unique[i].height != m->mh)
|
||||
{
|
||||
dirty = 1;
|
||||
m->num = i;
|
||||
m->mx = m->wx = unique[i].x_org;
|
||||
m->my = m->wy = unique[i].y_org;
|
||||
m->mw = m->ww = unique[i].width;
|
||||
m->mh = m->wh = unique[i].height;
|
||||
updatebarpos(m);
|
||||
}
|
||||
} else { /* less monitors available nn < n */
|
||||
for (i = nn; i < n; i++) {
|
||||
for (m = mons; m && m->next; m = m->next);
|
||||
while ((c = m->clients)) {
|
||||
dirty = 1;
|
||||
m->clients = c->next;
|
||||
detachstack(c);
|
||||
c->mon = mons;
|
||||
attach(c);
|
||||
attachaside(c);
|
||||
attachstack(c);
|
||||
}
|
||||
if (m == selmon)
|
||||
selmon = mons;
|
||||
cleanupmon(m);
|
||||
/* removed monitors if n > nn */
|
||||
for (i = nn; i < n; i++) {
|
||||
for (m = mons; m && m->next; m = m->next);
|
||||
while ((c = m->clients)) {
|
||||
dirty = 1;
|
||||
m->clients = c->next;
|
||||
detachstack(c);
|
||||
c->mon = mons;
|
||||
attach(c);
|
||||
attachbottom(c);
|
||||
attachstack(c);
|
||||
}
|
||||
if (m == selmon)
|
||||
selmon = mons;
|
||||
cleanupmon(m);
|
||||
}
|
||||
free(unique);
|
||||
} else
|
||||
|
@ -2177,16 +2185,15 @@ updatesizehints(Client *c)
|
|||
} else
|
||||
c->maxa = c->mina = 0.0;
|
||||
c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh);
|
||||
c->hintsvalid = 1;
|
||||
}
|
||||
|
||||
void
|
||||
updatestatus(void)
|
||||
{
|
||||
Monitor* m;
|
||||
if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
|
||||
strcpy(stext, "dwm-"VERSION);
|
||||
for(m = mons; m; m = m->next)
|
||||
drawbar(m);
|
||||
drawbar(selmon);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2383,4 +2390,3 @@ main(int argc, char *argv[])
|
|||
XCloseDisplay(dpy);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
/* ____ __ */
|
||||
/* / __ \_________ _/ /_____ */
|
||||
/* / / / / ___/ __ `/ //_/ _ \ */
|
||||
/* / /_/ / / / /_/ / ,< / __/ Clay Gomera (Drake) */
|
||||
/* /_____/_/ \__,_/_/|_|\___/ My custom dwm build */
|
||||
|
||||
void
|
||||
grid(Monitor *m) {
|
||||
unsigned int i, n, cx, cy, cw, ch, aw, ah, cols, rows;
|
||||
|
@ -31,3 +25,4 @@ grid(Monitor *m) {
|
|||
i++;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,5 @@
|
|||
/* ____ __ */
|
||||
/* / __ \_________ _/ /_____ */
|
||||
/* / / / / ___/ __ `/ //_/ _ \ */
|
||||
/* / /_/ / / / /_/ / ,< / __/ Clay Gomera (Drake) */
|
||||
/* /_____/_/ \__,_/_/|_|\___/ My custom dwm build */
|
||||
|
||||
/* cc transient.c -o transient -lX11 */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <X11/Xlib.h>
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
/* ____ __ */
|
||||
/* / __ \_________ _/ /_____ */
|
||||
/* / / / / ___/ __ `/ //_/ _ \ */
|
||||
/* / /_/ / / / /_/ / ,< / __/ Clay Gomera (Drake) */
|
||||
/* /_____/_/ \__,_/_/|_|\___/ My custom dwm build */
|
||||
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -38,4 +33,3 @@ die(const char *fmt, ...) {
|
|||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
/* ____ __ */
|
||||
/* / __ \_________ _/ /_____ */
|
||||
/* / / / / ___/ __ `/ //_/ _ \ */
|
||||
/* / /_/ / / / /_/ / ,< / __/ Clay Gomera (Drake) */
|
||||
/* /_____/_/ \__,_/_/|_|\___/ My custom dwm build */
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
|
||||
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
||||
|
@ -10,4 +6,3 @@
|
|||
|
||||
void die(const char *fmt, ...);
|
||||
void *ecalloc(size_t nmemb, size_t size);
|
||||
|
||||
|
|
Loading…
Reference in a new issue