├── patch ├── cmdcustomize.h ├── attachx.h ├── autostart.h ├── layout_deck.h ├── layout_grid.h ├── layout_tile.h ├── warp.h ├── cfacts.h ├── layout_bstack.h ├── layout_columns.h ├── pertag.h ├── swaptags.h ├── tagall.h ├── transfer.h ├── winview.h ├── zoomswap.h ├── bar_alternativetags.h ├── cool_autostart.h ├── dragcfact.h ├── dragmfact.h ├── fullscreen.h ├── killunsel.h ├── layout_horizgrid.h ├── layout_monocle.h ├── layout_nrowgrid.h ├── moveresize.h ├── movestack.h ├── shiftview.h ├── sticky.h ├── swapfocus.h ├── switchcol.h ├── tagallmon.h ├── tagswapmon.h ├── aspectresize.h ├── cyclelayouts.h ├── focusmaster.h ├── focusurgent.h ├── inplacerotate.h ├── layout_bstackhoriz.h ├── layout_gapplessgrid.h ├── setborderpx.h ├── transferall.h ├── layout_centeredmaster.h ├── reorganizetags.h ├── roundedcorners.h ├── sizehints_ruled.h ├── unfloatvisible.h ├── shiftviewclients.h ├── togglefullscreen.h ├── fakefullscreenclient.h ├── selfrestart.h ├── layout_centeredfloatingmaster.h ├── restartsig.h ├── bar_vtcolors.h ├── mdpcontrol.h ├── bar_alpha.h ├── bar_dwmblocks.h ├── bar_holdbar.h ├── insets.h ├── bar_alternativetags.c ├── push_no_master.h ├── rotatestack.h ├── moveplace.h ├── scratchpad.h ├── bar_tagicons.h ├── fsignal.h ├── bar_tags.h ├── sortscreens.h ├── sticky.c ├── bar_fancybar.h ├── bar_wintitle.h ├── push.h ├── bar_awesomebar.h ├── bar_ltsymbol.h ├── bar_statusbutton.h ├── bar_powerline_tags.h ├── combo.h ├── ipc │ ├── util.h │ ├── IPCClient.c │ ├── IPCClient.h │ ├── yajl_dumps.h │ └── util.c ├── bar_ewmhtags.h ├── cmdcustomize.c ├── maximize.h ├── ipc.h ├── bar_taggrid.h ├── bar_wintitleactions.h ├── focusmaster.c ├── restartsig.c ├── swallow.h ├── floatpos.h ├── layout_fibonacci.h ├── focusadjacenttag.h ├── zoomswap.c ├── exresize.h ├── tagothermonitor.h ├── scratchpad_alt_1.h ├── bar_statuscmd.h ├── decorationhints.h ├── unfloatvisible.c ├── bar_statusbutton.c ├── bar_ltsymbol.c ├── bar_status.h ├── bar_wintitle_hidden.h ├── focusurgent.c ├── bar_wintitle_floating.h ├── bar_statuscolors.c ├── insets.c ├── dwmc.h ├── shiftview.c ├── cfacts.c ├── stacker.h ├── cyclelayouts.c ├── bar_indicators.h ├── aspectresize.c ├── bar_powerline_status.h ├── winview.c ├── bar_status2d.h ├── bar_tabgroups.h ├── transferall.c ├── swaptags.c ├── warp.c ├── keymodes.h ├── togglefullscreen.c ├── fullscreen.c ├── sortscreens.c ├── switchcol.c ├── sizehints_ruled.c ├── killunsel.c ├── bar_status.c ├── swapfocus.c ├── bar_dwmblocks.c ├── bar_tagicons.c ├── tagall.c ├── reorganizetags.c ├── cool_autostart.c ├── fakefullscreenclient.c ├── tagothermonitor.c ├── moveplace.c ├── push_no_master.c ├── scratchpad.c ├── shiftviewclients.c ├── setborderpx.c ├── bar_flexwintitle.h ├── bar_holdbar.c ├── rotatestack.c ├── bar_alpha.c ├── transfer.c ├── combo.c ├── vanitygaps.h ├── decorationhints.c ├── attachx.c ├── layout_monocle.c ├── xrdb.h ├── bar_wintitle_hidden.c ├── bar_wintitle_floating.c ├── fsignal.c ├── bar_ewmhtags.c ├── tagallmon.c ├── bar_systray.h ├── movestack.c ├── push.c ├── roundedcorners.c ├── bar_wintitle.c ├── selfrestart.c ├── inplacerotate.c ├── layout_facts.c ├── bar_fancybar.c ├── bar_vtcolors.c ├── bar_statuscmd.c ├── stacker.c ├── layout_deck.c ├── moveresize.c ├── tagswapmon.c ├── maximize.c ├── layout_grid.c ├── bar_wintitleactions.c ├── bar_awesomebar.c ├── dragcfact.c ├── scratchpad_alt_1.c ├── layout_tile.c ├── layout_bstack.c ├── layout_columns.c ├── focusadjacenttag.c ├── layout_bstackhoriz.c ├── autostart.c ├── bar_tags.c ├── dwmc.c ├── layout_gapplessgrid.c ├── layout_nrowgrid.c ├── dwmc ├── pertag.c ├── ipc.c ├── layout_centeredfloatingmaster.c ├── layout_horizgrid.c ├── bar_powerline_tags.c ├── bar_powerline_status.c ├── bar_indicators.c ├── swallow.c ├── keymodes.c ├── mdpcontrol.c ├── layout_fibonacci.c ├── bar_taggrid.c ├── vanitygaps.c └── layout_centeredmaster.c ├── drw.o ├── dwm.o ├── siji.ttf ├── util.o ├── modwm.png ├── updatestatus.sh ├── util.h ├── util.c ├── layoutmenu.sh ├── transient.c ├── README ├── colors.h ├── Makefile ├── LICENSE ├── config.mk ├── tatami.c └── drw.h /patch/cmdcustomize.h: -------------------------------------------------------------------------------- 1 | static char* help(); -------------------------------------------------------------------------------- /patch/attachx.h: -------------------------------------------------------------------------------- 1 | static void attachx(Client *c); -------------------------------------------------------------------------------- /patch/autostart.h: -------------------------------------------------------------------------------- 1 | static void runautostart(void); -------------------------------------------------------------------------------- /patch/layout_deck.h: -------------------------------------------------------------------------------- 1 | static void deck(Monitor *m); -------------------------------------------------------------------------------- /patch/layout_grid.h: -------------------------------------------------------------------------------- 1 | static void grid(Monitor *m); -------------------------------------------------------------------------------- /patch/layout_tile.h: -------------------------------------------------------------------------------- 1 | static void tile(Monitor *); -------------------------------------------------------------------------------- /patch/warp.h: -------------------------------------------------------------------------------- 1 | static void warp(const Client *c); -------------------------------------------------------------------------------- /patch/cfacts.h: -------------------------------------------------------------------------------- 1 | static void setcfact(const Arg *arg); -------------------------------------------------------------------------------- /patch/layout_bstack.h: -------------------------------------------------------------------------------- 1 | static void bstack(Monitor *m); -------------------------------------------------------------------------------- /patch/layout_columns.h: -------------------------------------------------------------------------------- 1 | static void col(Monitor *); -------------------------------------------------------------------------------- /patch/pertag.h: -------------------------------------------------------------------------------- 1 | static void pertagview(const Arg *arg); -------------------------------------------------------------------------------- /patch/swaptags.h: -------------------------------------------------------------------------------- 1 | static void swaptags(const Arg *arg); -------------------------------------------------------------------------------- /patch/tagall.h: -------------------------------------------------------------------------------- 1 | static void tagall(const Arg *arg); -------------------------------------------------------------------------------- /patch/transfer.h: -------------------------------------------------------------------------------- 1 | static void transfer(const Arg *arg); -------------------------------------------------------------------------------- /patch/winview.h: -------------------------------------------------------------------------------- 1 | static void winview(const Arg* arg); -------------------------------------------------------------------------------- /patch/zoomswap.h: -------------------------------------------------------------------------------- 1 | static Client *findbefore(Client *c); -------------------------------------------------------------------------------- /patch/bar_alternativetags.h: -------------------------------------------------------------------------------- 1 | static void togglealttag(); -------------------------------------------------------------------------------- /patch/cool_autostart.h: -------------------------------------------------------------------------------- 1 | static void autostart_exec(void); -------------------------------------------------------------------------------- /patch/dragcfact.h: -------------------------------------------------------------------------------- 1 | static void dragcfact(const Arg *arg); -------------------------------------------------------------------------------- /patch/dragmfact.h: -------------------------------------------------------------------------------- 1 | static void dragmfact(const Arg *arg); -------------------------------------------------------------------------------- /patch/fullscreen.h: -------------------------------------------------------------------------------- 1 | static void fullscreen(const Arg *arg); -------------------------------------------------------------------------------- /patch/killunsel.h: -------------------------------------------------------------------------------- 1 | static void killunsel(const Arg *arg); -------------------------------------------------------------------------------- /patch/layout_horizgrid.h: -------------------------------------------------------------------------------- 1 | static void horizgrid(Monitor *m); -------------------------------------------------------------------------------- /patch/layout_monocle.h: -------------------------------------------------------------------------------- 1 | static void monocle(Monitor *m); -------------------------------------------------------------------------------- /patch/layout_nrowgrid.h: -------------------------------------------------------------------------------- 1 | static void nrowgrid(Monitor *m); -------------------------------------------------------------------------------- /patch/moveresize.h: -------------------------------------------------------------------------------- 1 | static void moveresize(const Arg *arg); -------------------------------------------------------------------------------- /patch/movestack.h: -------------------------------------------------------------------------------- 1 | static void movestack(const Arg *arg); -------------------------------------------------------------------------------- /patch/shiftview.h: -------------------------------------------------------------------------------- 1 | static void shiftview(const Arg *arg); -------------------------------------------------------------------------------- /patch/sticky.h: -------------------------------------------------------------------------------- 1 | static void togglesticky(const Arg *arg); -------------------------------------------------------------------------------- /patch/swapfocus.h: -------------------------------------------------------------------------------- 1 | static void swapfocus(const Arg *arg); -------------------------------------------------------------------------------- /patch/switchcol.h: -------------------------------------------------------------------------------- 1 | static void switchcol(const Arg *arg); -------------------------------------------------------------------------------- /patch/tagallmon.h: -------------------------------------------------------------------------------- 1 | static void tagallmon(const Arg *arg); -------------------------------------------------------------------------------- /patch/tagswapmon.h: -------------------------------------------------------------------------------- 1 | static void tagswapmon(const Arg *arg); -------------------------------------------------------------------------------- /drw.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plasmoduck/modwm/HEAD/drw.o -------------------------------------------------------------------------------- /dwm.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plasmoduck/modwm/HEAD/dwm.o -------------------------------------------------------------------------------- /patch/aspectresize.h: -------------------------------------------------------------------------------- 1 | static void aspectresize(const Arg *arg); -------------------------------------------------------------------------------- /patch/cyclelayouts.h: -------------------------------------------------------------------------------- 1 | static void cyclelayout(const Arg *arg); -------------------------------------------------------------------------------- /patch/focusmaster.h: -------------------------------------------------------------------------------- 1 | static void focusmaster(const Arg *arg); -------------------------------------------------------------------------------- /patch/focusurgent.h: -------------------------------------------------------------------------------- 1 | static void focusurgent(const Arg *arg); -------------------------------------------------------------------------------- /patch/inplacerotate.h: -------------------------------------------------------------------------------- 1 | static void inplacerotate(const Arg *arg); -------------------------------------------------------------------------------- /patch/layout_bstackhoriz.h: -------------------------------------------------------------------------------- 1 | static void bstackhoriz(Monitor *m); -------------------------------------------------------------------------------- /patch/layout_gapplessgrid.h: -------------------------------------------------------------------------------- 1 | static void gaplessgrid(Monitor *m); -------------------------------------------------------------------------------- /patch/setborderpx.h: -------------------------------------------------------------------------------- 1 | static void setborderpx(const Arg *arg); -------------------------------------------------------------------------------- /patch/transferall.h: -------------------------------------------------------------------------------- 1 | static void transferall(const Arg *arg); -------------------------------------------------------------------------------- /patch/layout_centeredmaster.h: -------------------------------------------------------------------------------- 1 | static void centeredmaster(Monitor *m); -------------------------------------------------------------------------------- /patch/reorganizetags.h: -------------------------------------------------------------------------------- 1 | static void reorganizetags(const Arg *arg); -------------------------------------------------------------------------------- /patch/roundedcorners.h: -------------------------------------------------------------------------------- 1 | static void drawroundedcorners(Client *c); -------------------------------------------------------------------------------- /patch/sizehints_ruled.h: -------------------------------------------------------------------------------- 1 | static void checkfloatingrules(Client *c); -------------------------------------------------------------------------------- /patch/unfloatvisible.h: -------------------------------------------------------------------------------- 1 | static void unfloatvisible(const Arg *arg); -------------------------------------------------------------------------------- /siji.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plasmoduck/modwm/HEAD/siji.ttf -------------------------------------------------------------------------------- /util.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plasmoduck/modwm/HEAD/util.o -------------------------------------------------------------------------------- /modwm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plasmoduck/modwm/HEAD/modwm.png -------------------------------------------------------------------------------- /patch/shiftviewclients.h: -------------------------------------------------------------------------------- 1 | static void shiftviewclients(const Arg *arg); -------------------------------------------------------------------------------- /patch/togglefullscreen.h: -------------------------------------------------------------------------------- 1 | static void togglefullscreen(const Arg *arg); -------------------------------------------------------------------------------- /patch/fakefullscreenclient.h: -------------------------------------------------------------------------------- 1 | static void togglefakefullscreen(const Arg *arg); -------------------------------------------------------------------------------- /patch/selfrestart.h: -------------------------------------------------------------------------------- 1 | char *get_dwm_path(); 2 | void self_restart(const Arg *arg); -------------------------------------------------------------------------------- /patch/layout_centeredfloatingmaster.h: -------------------------------------------------------------------------------- 1 | static void centeredfloatingmaster(Monitor *m); -------------------------------------------------------------------------------- /patch/restartsig.h: -------------------------------------------------------------------------------- 1 | static void sighup(int unused); 2 | static void sigterm(int unused); -------------------------------------------------------------------------------- /patch/bar_vtcolors.h: -------------------------------------------------------------------------------- 1 | static void get_vt_colors(void); 2 | static int get_luminance(char *rgb); -------------------------------------------------------------------------------- /patch/mdpcontrol.h: -------------------------------------------------------------------------------- 1 | static void mpdchange(const Arg *direction); 2 | static void mpdcontrol(); -------------------------------------------------------------------------------- /patch/bar_alpha.h: -------------------------------------------------------------------------------- 1 | #define OPAQUE 0xffU 2 | 3 | static void xinitvisual(); 4 | -------------------------------------------------------------------------------- /patch/bar_dwmblocks.h: -------------------------------------------------------------------------------- 1 | static int getdwmblockspid(); 2 | static void sigdwmblocks(const Arg *arg); -------------------------------------------------------------------------------- /patch/bar_holdbar.h: -------------------------------------------------------------------------------- 1 | static void keyrelease(XEvent *e); 2 | static void holdbar(const Arg *arg); -------------------------------------------------------------------------------- /patch/insets.h: -------------------------------------------------------------------------------- 1 | static void setinset(Monitor *m, Inset inset); 2 | static void updateinset(const Arg *arg); -------------------------------------------------------------------------------- /patch/bar_alternativetags.c: -------------------------------------------------------------------------------- 1 | void 2 | togglealttag() 3 | { 4 | selmon->alttag = !selmon->alttag; 5 | drawbar(selmon); 6 | } -------------------------------------------------------------------------------- /patch/push_no_master.h: -------------------------------------------------------------------------------- 1 | Client * prevt(Client *c); 2 | static void pushup(const Arg *arg); 3 | static void pushdown(const Arg *arg); -------------------------------------------------------------------------------- /patch/rotatestack.h: -------------------------------------------------------------------------------- 1 | static void enqueue(Client *c); 2 | static void enqueuestack(Client *c); 3 | static void rotatestack(const Arg *arg); -------------------------------------------------------------------------------- /patch/moveplace.h: -------------------------------------------------------------------------------- 1 | enum { WIN_NW, WIN_N, WIN_NE, WIN_W, WIN_C, WIN_E, WIN_SW, WIN_S, WIN_SE }; 2 | 3 | static void moveplace(const Arg *arg); -------------------------------------------------------------------------------- /patch/scratchpad.h: -------------------------------------------------------------------------------- 1 | typedef struct { 2 | const char *name; 3 | const void *cmd; 4 | } Sp; 5 | 6 | static void togglescratch(const Arg *arg); -------------------------------------------------------------------------------- /patch/bar_tagicons.h: -------------------------------------------------------------------------------- 1 | enum { 2 | DEFAULT_TAGS, 3 | ALTERNATIVE_TAGS, 4 | ALT_TAGS_DECORATION, 5 | }; 6 | 7 | static char * tagicon(Monitor *m, int tag); -------------------------------------------------------------------------------- /patch/fsignal.h: -------------------------------------------------------------------------------- 1 | typedef struct { 2 | unsigned int signum; 3 | void (*func)(const Arg *); 4 | const Arg arg; 5 | } Signal; 6 | 7 | static int fake_signal(void); -------------------------------------------------------------------------------- /patch/bar_tags.h: -------------------------------------------------------------------------------- 1 | static int width_tags(Bar *bar, BarArg *a); 2 | static int draw_tags(Bar *bar, BarArg *a); 3 | static int click_tags(Bar *bar, Arg *arg, BarArg *a); -------------------------------------------------------------------------------- /patch/sortscreens.h: -------------------------------------------------------------------------------- 1 | #define RIGHTOF(a,b) (a.y_org > b.y_org) || ((a.y_org == b.y_org) && (a.x_org > b.x_org)) 2 | 3 | static void sortscreens(XineramaScreenInfo *screens, int n); -------------------------------------------------------------------------------- /patch/sticky.c: -------------------------------------------------------------------------------- 1 | void 2 | togglesticky(const Arg *arg) 3 | { 4 | if (!selmon->sel) 5 | return; 6 | selmon->sel->issticky = !selmon->sel->issticky; 7 | arrange(selmon); 8 | } -------------------------------------------------------------------------------- /patch/bar_fancybar.h: -------------------------------------------------------------------------------- 1 | static int width_fancybar(Bar *bar, BarArg *a); 2 | static int draw_fancybar(Bar *bar, BarArg *a); 3 | static int click_fancybar(Bar *bar, Arg *arg, BarArg *a); -------------------------------------------------------------------------------- /patch/bar_wintitle.h: -------------------------------------------------------------------------------- 1 | static int width_wintitle(Bar *bar, BarArg *a); 2 | static int draw_wintitle(Bar *bar, BarArg *a); 3 | static int click_wintitle(Bar *bar, Arg *arg, BarArg *a); -------------------------------------------------------------------------------- /patch/push.h: -------------------------------------------------------------------------------- 1 | static Client * nextc(Client *c, float f); 2 | static Client * prevc(Client *c, float f); 3 | static void pushup(const Arg *arg); 4 | static void pushdown(const Arg *arg); -------------------------------------------------------------------------------- /patch/bar_awesomebar.h: -------------------------------------------------------------------------------- 1 | static int width_awesomebar(Bar *bar, BarArg *a); 2 | static int draw_awesomebar(Bar *bar, BarArg *a); 3 | static int click_awesomebar(Bar *bar, Arg *arg, BarArg *a); -------------------------------------------------------------------------------- /patch/bar_ltsymbol.h: -------------------------------------------------------------------------------- 1 | static int width_ltsymbol(Bar *bar, BarArg *a); 2 | static int draw_ltsymbol(Bar *bar, BarArg *a); 3 | static int click_ltsymbol(Bar *bar, Arg *arg, BarArg *a); 4 | -------------------------------------------------------------------------------- /patch/bar_statusbutton.h: -------------------------------------------------------------------------------- 1 | static int width_stbutton(Bar *bar, BarArg *a); 2 | static int draw_stbutton(Bar *bar, BarArg *a); 3 | static int click_stbutton(Bar *bar, Arg *arg, BarArg *a); -------------------------------------------------------------------------------- /patch/bar_powerline_tags.h: -------------------------------------------------------------------------------- 1 | static int width_pwrl_tags(Bar *bar, BarArg *a); 2 | static int draw_pwrl_tags(Bar *bar, BarArg *a); 3 | static int click_pwrl_tags(Bar *bar, Arg *arg, BarArg *a); -------------------------------------------------------------------------------- /patch/combo.h: -------------------------------------------------------------------------------- 1 | #if !BAR_HOLDBAR_PATCH 2 | static void keyrelease(XEvent *e); 3 | #endif // !BAR_HOLDBAR_PATCH 4 | static void combotag(const Arg *arg); 5 | static void comboview(const Arg *arg); -------------------------------------------------------------------------------- /patch/ipc/util.h: -------------------------------------------------------------------------------- 1 | int normalizepath(const char *path, char **normal); 2 | int mkdirp(const char *path); 3 | int parentdir(const char *path, char **parent); 4 | int nullterminate(char **str, size_t *len); -------------------------------------------------------------------------------- /patch/bar_ewmhtags.h: -------------------------------------------------------------------------------- 1 | static void setcurrentdesktop(void); 2 | static void setdesktopnames(void); 3 | static void setnumdesktops(void); 4 | static void setviewport(void); 5 | static void updatecurrentdesktop(void); -------------------------------------------------------------------------------- /patch/cmdcustomize.c: -------------------------------------------------------------------------------- 1 | char* 2 | help(void) 3 | { 4 | return "usage: dwm [-hv] [-fn font] [-nb color] [-nf color] [-sb color] [-sf color]\n[-df font] [-dnf color] [-dnb color] [-dsf color] [-dsb color]\n"; 5 | } -------------------------------------------------------------------------------- /patch/maximize.h: -------------------------------------------------------------------------------- 1 | static void maximize(int x, int y, int w, int h); 2 | static void togglemax(const Arg *arg); 3 | static void toggleverticalmax(const Arg *arg); 4 | static void togglehorizontalmax(const Arg *arg); -------------------------------------------------------------------------------- /patch/ipc.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | static int handlexevent(struct epoll_event *ev); 4 | static void setlayoutsafe(const Arg *arg); 5 | static void setupepoll(void); 6 | static void setstatus(const Arg *arg); -------------------------------------------------------------------------------- /updatestatus.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Place this script somewhere in $PATH and make a binding to update statusbar 3 | 4 | pidfile=/tmp/statbar-$(id -u)-$DISPLAY 5 | pid=$(cat "$pidfile") 6 | kill -SIGTRAP "$pid" 7 | 8 | -------------------------------------------------------------------------------- /patch/bar_taggrid.h: -------------------------------------------------------------------------------- 1 | static int width_taggrid(Bar *bar, BarArg *a); 2 | static int draw_taggrid(Bar *bar, BarArg *a); 3 | static int click_taggrid(Bar *bar, Arg *arg, BarArg *a); 4 | static void switchtag(const Arg *arg); -------------------------------------------------------------------------------- /patch/bar_wintitleactions.h: -------------------------------------------------------------------------------- 1 | static void hide(Client *c); 2 | static void show(Client *c); 3 | static void togglewin(const Arg *arg); 4 | static Client * prevtiled(Client *c); 5 | static void showhideclient(const Arg *arg); -------------------------------------------------------------------------------- /patch/focusmaster.c: -------------------------------------------------------------------------------- 1 | void 2 | focusmaster(const Arg *arg) 3 | { 4 | Client *c; 5 | 6 | if (selmon->nmaster < 1) 7 | return; 8 | 9 | c = nexttiled(selmon->clients); 10 | 11 | if (c) 12 | focus(c); 13 | } -------------------------------------------------------------------------------- /patch/restartsig.c: -------------------------------------------------------------------------------- 1 | static int restart = 0; 2 | 3 | void 4 | sighup(int unused) 5 | { 6 | Arg a = {.i = 1}; 7 | quit(&a); 8 | } 9 | 10 | void 11 | sigterm(int unused) 12 | { 13 | Arg a = {.i = 0}; 14 | quit(&a); 15 | } -------------------------------------------------------------------------------- /patch/swallow.h: -------------------------------------------------------------------------------- 1 | static pid_t getparentprocess(pid_t p); 2 | static int isdescprocess(pid_t p, pid_t c); 3 | static Client *swallowingclient(Window w); 4 | static Client *termforwin(const Client *c); 5 | static pid_t winpid(Window w); -------------------------------------------------------------------------------- /patch/floatpos.h: -------------------------------------------------------------------------------- 1 | static void floatpos(const Arg *arg); 2 | static void setfloatpos(Client *c, const char *floatpos); 3 | static void getfloatpos(int pos, char pCh, int size, char sCh, int min_p, int max_s, int cp, int cs, int cbw, int defgrid, int *out_p, int *out_s); -------------------------------------------------------------------------------- /patch/layout_fibonacci.h: -------------------------------------------------------------------------------- 1 | #if FIBONACCI_DWINDLE_LAYOUT 2 | static void dwindle(Monitor *m); 3 | #endif // FIBONACCI_DWINDLE_LAYOUT 4 | static void fibonacci(Monitor *m, int s); 5 | #if FIBONACCI_SPIRAL_LAYOUT 6 | static void spiral(Monitor *m); 7 | #endif // FIBONACCI_SPIRAL_LAYOUT -------------------------------------------------------------------------------- /patch/focusadjacenttag.h: -------------------------------------------------------------------------------- 1 | static void tagtoleft(const Arg *arg); 2 | static void tagtoright(const Arg *arg); 3 | static void viewtoleft(const Arg *arg); 4 | static void viewtoright(const Arg *arg); 5 | static void tagandviewtoleft(const Arg *arg); 6 | static void tagandviewtoright(const Arg *arg); -------------------------------------------------------------------------------- /patch/zoomswap.c: -------------------------------------------------------------------------------- 1 | 2 | #if !PERTAG_PATCH 3 | static Client *prevzoom = NULL; 4 | #endif // PERTAG_PATCH 5 | 6 | Client * 7 | findbefore(Client *c) { 8 | Client *p; 9 | if (!c || c == c->mon->clients) 10 | return NULL; 11 | for (p = c->mon->clients; p && p->next != c; p = p->next); 12 | return p; 13 | } -------------------------------------------------------------------------------- /patch/exresize.h: -------------------------------------------------------------------------------- 1 | enum { EX_NW, EX_N, EX_NE, EX_W, EX_C, EX_E, EX_SW, EX_S, EX_SE }; 2 | 3 | void expand(unsigned char mask); 4 | void togglemaximize(const Arg *arg); 5 | void toggleverticalexpand(const Arg *arg); 6 | void togglehorizontalexpand(const Arg *arg); 7 | void exresize(const Arg *arg); 8 | void explace(const Arg *arg); -------------------------------------------------------------------------------- /patch/tagothermonitor.h: -------------------------------------------------------------------------------- 1 | #if IPC_PATCH || DWMC_PATCH 2 | static void tagnextmonex(const Arg *arg); 3 | static void tagprevmonex(const Arg *arg); 4 | #endif // IPC_PATCH | DWMC_PATCH 5 | 6 | static void tagnextmon(const Arg *arg); 7 | static void tagprevmon(const Arg *arg); 8 | static void tagothermon(const Arg *arg, int dir); 9 | -------------------------------------------------------------------------------- /patch/scratchpad_alt_1.h: -------------------------------------------------------------------------------- 1 | #define SCRATCHPAD_MASK (1u << NUMTAGS) 2 | 3 | static void scratchpad_hide (); 4 | static _Bool scratchpad_last_showed_is_killed (void); 5 | static void scratchpad_remove (); 6 | static void scratchpad_show (); 7 | static void scratchpad_show_client (Client * c); 8 | static void scratchpad_show_first (void); -------------------------------------------------------------------------------- /patch/bar_statuscmd.h: -------------------------------------------------------------------------------- 1 | static int click_statuscmd(Bar *bar, Arg *arg, BarArg *a); 2 | #if BAR_EXTRASTATUS_PATCH 3 | static int click_statuscmd_es(Bar *bar, Arg *arg, BarArg *a); 4 | #endif // BAR_EXTRASTATUS_PATCH 5 | static int click_statuscmd_text(Arg *arg, int rel_x, char *text); 6 | static void copyvalidchars(char *text, char *rawtext); -------------------------------------------------------------------------------- /patch/decorationhints.h: -------------------------------------------------------------------------------- 1 | #define MWM_HINTS_FLAGS_FIELD 0 2 | #define MWM_HINTS_DECORATIONS_FIELD 2 3 | #define MWM_HINTS_DECORATIONS (1 << 1) 4 | #define MWM_DECOR_ALL (1 << 0) 5 | #define MWM_DECOR_BORDER (1 << 1) 6 | #define MWM_DECOR_TITLE (1 << 3) 7 | 8 | static void updatemotifhints(Client *c); -------------------------------------------------------------------------------- /patch/unfloatvisible.c: -------------------------------------------------------------------------------- 1 | void 2 | unfloatvisible(const Arg *arg) 3 | { 4 | Client *c; 5 | 6 | for (c = selmon->clients; c; c = c->next) 7 | if (ISVISIBLE(c) && c->isfloating) 8 | c->isfloating = c->isfixed; 9 | 10 | if (arg && arg->v) 11 | setlayout(arg); 12 | else 13 | arrange(selmon); 14 | } -------------------------------------------------------------------------------- /patch/bar_statusbutton.c: -------------------------------------------------------------------------------- 1 | int 2 | width_stbutton(Bar *bar, BarArg *a) 3 | { 4 | return TEXTW(buttonbar); 5 | } 6 | 7 | int 8 | draw_stbutton(Bar *bar, BarArg *a) 9 | { 10 | return drw_text(drw, a->x, a->y, a->w, a->h, lrpad / 2, buttonbar, 0, False); 11 | } 12 | 13 | int 14 | click_stbutton(Bar *bar, Arg *arg, BarArg *a) 15 | { 16 | return ClkButton; 17 | } 18 | -------------------------------------------------------------------------------- /patch/bar_ltsymbol.c: -------------------------------------------------------------------------------- 1 | int 2 | width_ltsymbol(Bar *bar, BarArg *a) 3 | { 4 | return TEXTW(bar->mon->ltsymbol); 5 | } 6 | 7 | int 8 | draw_ltsymbol(Bar *bar, BarArg *a) 9 | { 10 | return drw_text(drw, a->x, a->y, a->w, a->h, lrpad / 2, bar->mon->ltsymbol, 0, False); 11 | } 12 | 13 | int 14 | click_ltsymbol(Bar *bar, Arg *arg, BarArg *a) 15 | { 16 | return ClkLtSymbol; 17 | } -------------------------------------------------------------------------------- /patch/bar_status.h: -------------------------------------------------------------------------------- 1 | static int width_status(Bar *bar, BarArg *a); 2 | #if BAR_EXTRASTATUS_PATCH 3 | static int width_status_es(Bar *bar, BarArg *a); 4 | #endif // BAR_EXTRASTATUS_PATCH 5 | static int draw_status(Bar *bar, BarArg *a); 6 | #if BAR_EXTRASTATUS_PATCH 7 | static int draw_status_es(Bar *bar, BarArg *a); 8 | #endif // BAR_EXTRASTATUS_PATCH 9 | static int click_status(Bar *bar, Arg *arg, BarArg *a); -------------------------------------------------------------------------------- /patch/bar_wintitle_hidden.h: -------------------------------------------------------------------------------- 1 | static int width_wintitle_hidden(Bar *bar, BarArg *a); 2 | static int draw_wintitle_hidden(Bar *bar, BarArg *a); 3 | static int click_wintitle_hidden(Bar *bar, Arg *arg, BarArg *a); 4 | static int calc_wintitle_hidden( 5 | Monitor *m, int offx, int tabw, int passx, 6 | void(*tabfn)(Monitor *, Client *, int, int, int, int, Arg *arg, BarArg *barg), 7 | Arg *arg, BarArg *barg 8 | ); -------------------------------------------------------------------------------- /util.h: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | 3 | #ifndef MAX 4 | #define MAX(A, B) ((A) > (B) ? (A) : (B)) 5 | #endif 6 | #ifndef MIN 7 | #define MIN(A, B) ((A) < (B) ? (A) : (B)) 8 | #endif 9 | #define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B)) 10 | 11 | void die(const char *fmt, ...); 12 | void *ecalloc(size_t nmemb, size_t size); 13 | -------------------------------------------------------------------------------- /patch/focusurgent.c: -------------------------------------------------------------------------------- 1 | void 2 | focusurgent(const Arg *arg) 3 | { 4 | Client *c; 5 | int i; 6 | for (c = selmon->clients; c && !c->isurgent; c = c->next); 7 | if (c) { 8 | for (i = 0; i < NUMTAGS && !((1 << i) & c->tags); i++); 9 | if (i < NUMTAGS) { 10 | if (((1 << i) & TAGMASK) != selmon->tagset[selmon->seltags]) 11 | view(&((Arg) { .ui = 1 << i })); 12 | focus(c); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /patch/bar_wintitle_floating.h: -------------------------------------------------------------------------------- 1 | static int width_wintitle_floating(Bar *bar, BarArg *a); 2 | static int draw_wintitle_floating(Bar *bar, BarArg *a); 3 | static int click_wintitle_floating(Bar *bar, Arg *arg, BarArg *a); 4 | static int calc_wintitle_floating( 5 | Monitor *m, int offx, int tabw, int passx, 6 | void(*tabfn)(Monitor *, Client *, int, int, int, int, Arg *arg, BarArg *barg), 7 | Arg *arg, BarArg *barg 8 | ); -------------------------------------------------------------------------------- /patch/bar_statuscolors.c: -------------------------------------------------------------------------------- 1 | int 2 | textw_wosc(char *s) 3 | { 4 | char *ts = s; 5 | char *tp = s; 6 | int sw = 0; 7 | char ctmp; 8 | while (1) { 9 | if ((unsigned int)*ts > LENGTH(colors)) { 10 | ts++; 11 | continue; 12 | } 13 | ctmp = *ts; 14 | *ts = '\0'; 15 | sw += drw_fontset_getwidth(drw, tp, True); 16 | *ts = ctmp; 17 | if (ctmp == '\0') 18 | break; 19 | tp = ++ts; 20 | } 21 | 22 | return sw; 23 | } -------------------------------------------------------------------------------- /patch/insets.c: -------------------------------------------------------------------------------- 1 | void 2 | setinset(Monitor *m, Inset inset) 3 | { 4 | Bar *bar; 5 | m->inset = inset; 6 | updatebarpos(m); 7 | for (bar = m->bar; bar; bar = bar->next) 8 | XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh); 9 | arrange(m); 10 | } 11 | 12 | void 13 | updateinset(const Arg *arg) 14 | { 15 | Inset *inset = (Inset *)arg->v; 16 | for (Monitor *m = mons; m; m = m->next) 17 | setinset(m, *inset); 18 | } -------------------------------------------------------------------------------- /patch/dwmc.h: -------------------------------------------------------------------------------- 1 | typedef struct { 2 | const char * sig; 3 | void (*func)(const Arg *); 4 | } Signal; 5 | 6 | static void setlayoutex(const Arg *arg); 7 | static void viewex(const Arg *arg); 8 | static void viewallex(const Arg *arg); 9 | static void toggleviewex(const Arg *arg); 10 | static void tagex(const Arg *arg); 11 | static void toggletagex(const Arg *arg); 12 | static void tagallex(const Arg *arg); 13 | static int fake_signal(void); 14 | -------------------------------------------------------------------------------- /patch/shiftview.c: -------------------------------------------------------------------------------- 1 | void 2 | shiftview(const Arg *arg) 3 | { 4 | Arg shifted; 5 | 6 | if (arg->i > 0) // left circular shift 7 | shifted.ui = (selmon->tagset[selmon->seltags] << arg->i) 8 | | (selmon->tagset[selmon->seltags] >> (NUMTAGS - arg->i)); 9 | 10 | else // right circular shift 11 | shifted.ui = selmon->tagset[selmon->seltags] >> (- arg->i) 12 | | selmon->tagset[selmon->seltags] << (NUMTAGS + arg->i); 13 | 14 | view(&shifted); 15 | } 16 | -------------------------------------------------------------------------------- /patch/cfacts.c: -------------------------------------------------------------------------------- 1 | void 2 | setcfact(const Arg *arg) 3 | { 4 | float f; 5 | Client *c; 6 | 7 | c = selmon->sel; 8 | 9 | if (!arg || !c || !selmon->lt[selmon->sellt]->arrange) 10 | return; 11 | if (!arg->f) 12 | f = 1.0; 13 | else if (arg->f > 4.0) // set fact absolutely 14 | f = arg->f - 4.0; 15 | else 16 | f = arg->f + c->cfact; 17 | if (f < 0.25) 18 | f = 0.25; 19 | else if (f > 4.0) 20 | f = 4.0; 21 | c->cfact = f; 22 | arrange(selmon); 23 | } -------------------------------------------------------------------------------- /patch/stacker.h: -------------------------------------------------------------------------------- 1 | #define GETINC(X) ((X) - 2000) 2 | #define INC(X) ((X) + 2000) 3 | #define ISINC(X) ((X) > 1000 && (X) < 3000) 4 | #define PREVSEL 3000 5 | #define MOD(N,M) ((N)%(M) < 0 ? (N)%(M) + (M) : (N)%(M)) 6 | #define TRUNC(X,A,B) (MAX((A), MIN((X), (B)))) 7 | 8 | static void focusstack(const Arg *arg); 9 | static void pushstack(const Arg *arg); 10 | static int stackpos(const Arg *arg); -------------------------------------------------------------------------------- /patch/cyclelayouts.c: -------------------------------------------------------------------------------- 1 | void 2 | cyclelayout(const Arg *arg) 3 | { 4 | Layout *l; 5 | for (l = (Layout *)layouts; l != selmon->lt[selmon->sellt]; l++); 6 | if (arg->i > 0) { 7 | if (l->symbol && (l + 1)->symbol) 8 | setlayout(&((Arg) { .v = (l + 1) })); 9 | else 10 | setlayout(&((Arg) { .v = layouts })); 11 | } else { 12 | if (l != layouts && (l - 1)->symbol) 13 | setlayout(&((Arg) { .v = (l - 1) })); 14 | else 15 | setlayout(&((Arg) { .v = &layouts[LENGTH(layouts) - 2] })); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /patch/bar_indicators.h: -------------------------------------------------------------------------------- 1 | enum { 2 | INDICATOR_NONE, 3 | INDICATOR_TOP_LEFT_SQUARE, 4 | INDICATOR_TOP_LEFT_LARGER_SQUARE, 5 | INDICATOR_TOP_BAR, 6 | INDICATOR_TOP_BAR_SLIM, 7 | INDICATOR_BOTTOM_BAR, 8 | INDICATOR_BOTTOM_BAR_SLIM, 9 | INDICATOR_BOX, 10 | INDICATOR_BOX_WIDER, 11 | INDICATOR_BOX_FULL, 12 | INDICATOR_CLIENT_DOTS, 13 | INDICATOR_RIGHT_TAGS 14 | }; 15 | 16 | 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); -------------------------------------------------------------------------------- /patch/aspectresize.c: -------------------------------------------------------------------------------- 1 | void 2 | aspectresize(const Arg *arg) 3 | { 4 | /* only floating windows can be moved */ 5 | Client *c; 6 | c = selmon->sel; 7 | float ratio; 8 | int w, h,nw, nh; 9 | 10 | if (!c || !arg) 11 | return; 12 | if (selmon->lt[selmon->sellt]->arrange && !c->isfloating) 13 | return; 14 | 15 | ratio = (float)c->w / (float)c->h; 16 | h = arg->i; 17 | w = (int)(ratio * h); 18 | 19 | nw = c->w + w; 20 | nh = c->h + h; 21 | 22 | XRaiseWindow(dpy, c->win); 23 | resize(c, c->x, c->y, nw, nh, True); 24 | } -------------------------------------------------------------------------------- /patch/bar_powerline_status.h: -------------------------------------------------------------------------------- 1 | static int width_pwrl_status(Bar *bar, BarArg *a); 2 | #if BAR_EXTRASTATUS_PATCH 3 | static int width_pwrl_status_es(Bar *bar, BarArg *a); 4 | #endif // BAR_EXTRASTATUS_PATCH 5 | static int draw_pwrl_status(Bar *bar, BarArg *a); 6 | #if BAR_EXTRASTATUS_PATCH 7 | static int draw_pwrl_status_es(Bar *bar, BarArg *a); 8 | #endif // BAR_EXTRASTATUS_PATCH 9 | static int click_pwrl_status(Bar *bar, Arg *arg, BarArg *a); 10 | static int drawpowerlinestatus(int x, char *stext, BarArg *a); 11 | static int widthpowerlinestatus(char *stext); -------------------------------------------------------------------------------- /patch/winview.c: -------------------------------------------------------------------------------- 1 | /* Selects for the view of the focused window. The list of tags */ 2 | /* to be displayed is matched to the focused window tag list. */ 3 | void 4 | winview(const Arg* arg) 5 | { 6 | Window win, win_r, win_p, *win_c; 7 | unsigned nc; 8 | int unused; 9 | Client* c; 10 | Arg a; 11 | 12 | if (!XGetInputFocus(dpy, &win, &unused)) return; 13 | while (XQueryTree(dpy, win, &win_r, &win_p, &win_c, &nc) 14 | && win_p != win_r) win = win_p; 15 | 16 | if (!(c = wintoclient(win))) return; 17 | 18 | a.ui = c->tags; 19 | view(&a); 20 | } -------------------------------------------------------------------------------- /patch/bar_status2d.h: -------------------------------------------------------------------------------- 1 | static int width_status2d(Bar *bar, BarArg *a); 2 | #if BAR_EXTRASTATUS_PATCH 3 | static int width_status2d_es(Bar *bar, BarArg *a); 4 | #endif // BAR_EXTRASTATUS_PATCH 5 | static int draw_status2d(Bar *bar, BarArg *a); 6 | #if BAR_EXTRASTATUS_PATCH 7 | static int draw_status2d_es(Bar *bar, BarArg *a); 8 | #endif // BAR_EXTRASTATUS_PATCH 9 | #if !BAR_STATUSCMD_PATCH 10 | static int click_status2d(Bar *bar, Arg *arg, BarArg *a); 11 | #endif // BAR_STATUSCMD_PATCH 12 | static int drawstatusbar(BarArg *a, char *text); 13 | static int status2dtextlength(char *stext); -------------------------------------------------------------------------------- /patch/bar_tabgroups.h: -------------------------------------------------------------------------------- 1 | static int width_bartabgroups(Bar *bar, BarArg *a); 2 | static int draw_bartabgroups(Bar *bar, BarArg *a); 3 | static int click_bartabgroups(Bar *bar, Arg *arg, BarArg *a); 4 | 5 | static void bartabdraw(Monitor *m, Client *c, int unused, int x, int w, int groupactive, Arg *arg, BarArg *barg); 6 | static void bartabclick(Monitor *m, Client *c, int passx, int x, int w, int unused, Arg *arg, BarArg *barg); 7 | static int bartabcalculate(Monitor *m, int offx, int w, int passx, void(*tabfn)(Monitor *, Client *, int, int, int, int, Arg *arg, BarArg *barg), Arg *arg, BarArg *barg); -------------------------------------------------------------------------------- /patch/transferall.c: -------------------------------------------------------------------------------- 1 | void 2 | transferall(const Arg *arg) 3 | { 4 | Client *c, *n = selmon->clients, *attachfrom = NULL; 5 | int i = 0, nstackclients = 0; 6 | while (n) { 7 | c = n; 8 | n = c->next; 9 | if (!ISVISIBLE(c) || c->isfloating) continue; 10 | if (i >= selmon->nmaster) { 11 | detach(c); 12 | if (!attachfrom) { 13 | attach(c); 14 | } else { 15 | c->next = attachfrom->next; 16 | attachfrom->next = c; 17 | } 18 | attachfrom = c; 19 | nstackclients++; 20 | } 21 | i++; 22 | } 23 | selmon->nmaster = nstackclients; 24 | arrange(selmon); 25 | } -------------------------------------------------------------------------------- /patch/swaptags.c: -------------------------------------------------------------------------------- 1 | void 2 | swaptags(const Arg *arg) 3 | { 4 | unsigned int newtag = arg->ui & TAGMASK; 5 | unsigned int curtag = selmon->tagset[selmon->seltags]; 6 | 7 | if (newtag == curtag || !curtag || (curtag & (curtag-1))) 8 | return; 9 | 10 | for (Client *c = selmon->clients; c != NULL; c = c->next) { 11 | if ((c->tags & newtag) || (c->tags & curtag)) 12 | c->tags ^= curtag ^ newtag; 13 | 14 | if (!c->tags) 15 | c->tags = newtag; 16 | } 17 | 18 | selmon->tagset[selmon->seltags] = newtag; 19 | 20 | focus(NULL); 21 | arrange(selmon); 22 | } -------------------------------------------------------------------------------- /patch/warp.c: -------------------------------------------------------------------------------- 1 | void 2 | warp(const Client *c) 3 | { 4 | int x, y; 5 | 6 | if (!c) { 7 | XWarpPointer(dpy, None, root, 0, 0, 0, 0, selmon->wx + selmon->ww / 2, selmon->wy + selmon->wh / 2); 8 | return; 9 | } 10 | 11 | if (!getrootptr(&x, &y) || 12 | (x > c->x - c->bw && 13 | y > c->y - c->bw && 14 | x < c->x + c->w + c->bw*2 && 15 | y < c->y + c->h + c->bw*2) || 16 | x < c->mon->wx || 17 | x > c->mon->wx + c->mon->ww || 18 | y < c->mon->wy || 19 | y > c->mon->wy + c->mon->wh 20 | ) 21 | return; 22 | 23 | XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); 24 | } 25 | -------------------------------------------------------------------------------- /patch/keymodes.h: -------------------------------------------------------------------------------- 1 | #define COMMANDMODE 1 2 | #define INSERTMODE 2 3 | 4 | typedef struct { 5 | unsigned int mod[4]; 6 | KeySym keysym[4]; 7 | void (*func)(const Arg *); 8 | const Arg arg; 9 | } Command; 10 | 11 | static void clearcmd(const Arg *arg); 12 | static void grabkeys(void); 13 | static int isprotodel(Client *c); 14 | static void keypress(XEvent *e); 15 | static void onlyclient(const Arg *arg); 16 | static void setkeymode(const Arg *arg); 17 | 18 | /* variables */ 19 | static unsigned int cmdmod[4]; 20 | static unsigned int keymode = INSERTMODE; 21 | static KeySym cmdkeysym[4]; -------------------------------------------------------------------------------- /patch/togglefullscreen.c: -------------------------------------------------------------------------------- 1 | void 2 | togglefullscreen(const Arg *arg) 3 | { 4 | Client *c = selmon->sel; 5 | if (!c) 6 | return; 7 | 8 | #if !FAKEFULLSCREEN_PATCH && FAKEFULLSCREEN_CLIENT_PATCH 9 | if (c->fakefullscreen == 1) { 10 | c->fakefullscreen = 2; 11 | if (c->isfullscreen) 12 | c->isfullscreen = 0; 13 | } else if (c->fakefullscreen == 2) { 14 | c->fakefullscreen = 0; 15 | togglefakefullscreen(NULL); 16 | arrange(selmon); 17 | return; 18 | } 19 | #endif // FAKEFULLSCREEN_CLIENT_PATCH 20 | 21 | setfullscreen(c, !c->isfullscreen); 22 | if (!c->isfullscreen) 23 | arrange(c->mon); 24 | } 25 | -------------------------------------------------------------------------------- /patch/fullscreen.c: -------------------------------------------------------------------------------- 1 | Layout *last_layout; 2 | 3 | void 4 | fullscreen(const Arg *arg) 5 | { 6 | int monocle_pos = 0; 7 | if (selmon->showbar || last_layout == NULL) { 8 | #if MONOCLE_LAYOUT 9 | for (monocle_pos = 0, last_layout = (Layout *)layouts; !last_layout->arrange || last_layout->arrange != &monocle; monocle_pos++, last_layout++ ); 10 | #endif // MONOCLE_LAYOUT 11 | for (last_layout = (Layout *)layouts; last_layout != selmon->lt[selmon->sellt]; last_layout++); 12 | setlayout(&((Arg) { .v = &layouts[monocle_pos] })); 13 | } else { 14 | setlayout(&((Arg) { .v = last_layout })); 15 | } 16 | togglebar(arg); 17 | } -------------------------------------------------------------------------------- /patch/sortscreens.c: -------------------------------------------------------------------------------- 1 | void 2 | sortscreens(XineramaScreenInfo *screens, int n) 3 | { 4 | int i, j; 5 | XineramaScreenInfo *screen = ecalloc(1, sizeof(XineramaScreenInfo)); 6 | 7 | for (i = 0; i < n; i++) 8 | for (j = i + 1; j < n; j++) 9 | if (RIGHTOF(screens[i], screens[j])) { 10 | memcpy(&screen[0], &screens[i], sizeof(XineramaScreenInfo)); 11 | memcpy(&screens[i], &screens[j], sizeof(XineramaScreenInfo)); 12 | memcpy(&screens[j], &screen[0], sizeof(XineramaScreenInfo)); 13 | } 14 | XFree(screen); 15 | } -------------------------------------------------------------------------------- /util.c: -------------------------------------------------------------------------------- 1 | /* See LICENSE file for copyright and license details. */ 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "util.h" 8 | 9 | void * 10 | ecalloc(size_t nmemb, size_t size) 11 | { 12 | void *p; 13 | 14 | if (!(p = calloc(nmemb, size))) 15 | die("calloc:"); 16 | return p; 17 | } 18 | 19 | void 20 | die(const char *fmt, ...) { 21 | va_list ap; 22 | 23 | va_start(ap, fmt); 24 | vfprintf(stderr, fmt, ap); 25 | va_end(ap); 26 | 27 | if (fmt[0] && fmt[strlen(fmt)-1] == ':') { 28 | fputc(' ', stderr); 29 | perror(NULL); 30 | } else { 31 | fputc('\n', stderr); 32 | } 33 | 34 | exit(1); 35 | } 36 | -------------------------------------------------------------------------------- /patch/switchcol.c: -------------------------------------------------------------------------------- 1 | void 2 | switchcol(const Arg *arg) 3 | { 4 | Client *c, *t; 5 | int col = 0; 6 | int i; 7 | 8 | if (!selmon->sel) 9 | return; 10 | for (i = 0, c = nexttiled(selmon->clients); c ; 11 | c = nexttiled(c->next), i++) { 12 | if (c == selmon->sel) 13 | col = (i + 1) > selmon->nmaster; 14 | } 15 | if (i <= selmon->nmaster) 16 | return; 17 | for (c = selmon->stack; c; c = c->snext) { 18 | if (!ISVISIBLE(c)) 19 | continue; 20 | for (i = 0, t = nexttiled(selmon->clients); t && t != c; 21 | t = nexttiled(t->next), i++); 22 | if (t && (i + 1 > selmon->nmaster) != col) { 23 | focus(c); 24 | restack(selmon); 25 | break; 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /patch/sizehints_ruled.c: -------------------------------------------------------------------------------- 1 | void 2 | checkfloatingrules(Client *c) 3 | { 4 | const char *class, *instance; 5 | unsigned int i; 6 | const Rule *r; 7 | XClassHint ch = { NULL, NULL }; 8 | 9 | XGetClassHint(dpy, c->win, &ch); 10 | class = ch.res_class ? ch.res_class : broken; 11 | instance = ch.res_name ? ch.res_name : broken; 12 | 13 | for (i = 0; i < LENGTH(rules); i++) { 14 | r = &rules[i]; 15 | if ((!r->title || strstr(c->name, r->title)) 16 | && (!r->class || strstr(class, r->class)) 17 | && (!r->instance || strstr(instance, r->instance))) 18 | c->isfloating = r->isfloating; 19 | } 20 | if (ch.res_class) 21 | XFree(ch.res_class); 22 | if (ch.res_name) 23 | XFree(ch.res_name); 24 | } 25 | -------------------------------------------------------------------------------- /patch/killunsel.c: -------------------------------------------------------------------------------- 1 | void 2 | killunsel(const Arg *arg) 3 | { 4 | Client *i = NULL; 5 | 6 | if (!selmon->sel) 7 | return; 8 | 9 | for (i = selmon->clients; i; i = i->next) { 10 | if (ISVISIBLE(i) && i != selmon->sel) { 11 | #if BAR_SYSTRAY_PATCH 12 | if (!sendevent(i->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0, 0, 0)) 13 | #else 14 | if (!sendevent(i, wmatom[WMDelete])) 15 | #endif // BAR_SYSTRAY_PATCH 16 | { 17 | XGrabServer(dpy); 18 | XSetErrorHandler(xerrordummy); 19 | XSetCloseDownMode(dpy, DestroyAll); 20 | XKillClient(dpy, i->win); 21 | XSync(dpy, False); 22 | XSetErrorHandler(xerror); 23 | XUngrabServer(dpy); 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /patch/bar_status.c: -------------------------------------------------------------------------------- 1 | int 2 | width_status(Bar *bar, BarArg *a) 3 | { 4 | return TEXTWM(stext); 5 | } 6 | 7 | #if BAR_EXTRASTATUS_PATCH 8 | int 9 | width_status_es(Bar *bar, BarArg *a) 10 | { 11 | return TEXTWM(estext) - lrpad; 12 | } 13 | #endif // BAR_EXTRASTATUS_PATCH 14 | 15 | int 16 | draw_status(Bar *bar, BarArg *a) 17 | { 18 | return drw_text(drw, a->x, a->y, a->w, a->h, lrpad / 2, stext, 0, True); 19 | } 20 | 21 | #if BAR_EXTRASTATUS_PATCH 22 | int 23 | draw_status_es(Bar *bar, BarArg *a) 24 | { 25 | return drw_text(drw, a->x, a->y, a->w, a->h, 0, estext, 0, True); 26 | } 27 | #endif // BAR_EXTRASTATUS_PATCH 28 | 29 | int 30 | click_status(Bar *bar, Arg *arg, BarArg *a) 31 | { 32 | return ClkStatusText; 33 | } 34 | -------------------------------------------------------------------------------- /patch/swapfocus.c: -------------------------------------------------------------------------------- 1 | void 2 | swapfocus(const Arg *arg) 3 | { 4 | if (!selmon->sel) 5 | return; 6 | if (selmon->pertag->prevclient[selmon->pertag->curtag] != NULL 7 | && ISVISIBLE(selmon->pertag->prevclient[selmon->pertag->curtag])) { 8 | focus(selmon->pertag->prevclient[selmon->pertag->curtag]); 9 | restack(selmon->pertag->prevclient[selmon->pertag->curtag]->mon); 10 | } 11 | else { 12 | Client *c = NULL; 13 | for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); 14 | if (!c) 15 | for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); 16 | if (c) { 17 | focus(c); 18 | restack(selmon); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /patch/bar_dwmblocks.c: -------------------------------------------------------------------------------- 1 | static int dwmblockssig; 2 | pid_t dwmblockspid = 0; 3 | 4 | int 5 | getdwmblockspid() 6 | { 7 | char buf[16]; 8 | FILE *fp = popen("pidof -s dwmblocks", "r"); 9 | if (fgets(buf, sizeof(buf), fp)); 10 | pid_t pid = strtoul(buf, NULL, 10); 11 | pclose(fp); 12 | dwmblockspid = pid; 13 | return pid != 0 ? 0 : -1; 14 | } 15 | 16 | void 17 | sigdwmblocks(const Arg *arg) 18 | { 19 | union sigval sv; 20 | sv.sival_int = (dwmblockssig << 8) | arg->i; 21 | if (!dwmblockspid) 22 | if (getdwmblockspid() == -1) 23 | return; 24 | 25 | if (sigqueue(dwmblockspid, SIGUSR1, sv) == -1) { 26 | if (errno == ESRCH) { 27 | if (!getdwmblockspid()) 28 | sigqueue(dwmblockspid, SIGUSR1, sv); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /patch/bar_tagicons.c: -------------------------------------------------------------------------------- 1 | char * 2 | tagicon(Monitor *m, int tag) 3 | { 4 | #if BAR_ALTTAGSDECORATION_PATCH 5 | Client *c; 6 | #endif // BAR_ALTTAGSDECORATION_PATCH 7 | int tagindex = tag + NUMTAGS * m->index; 8 | if (tagindex >= LENGTH(tagicons[DEFAULT_TAGS])) 9 | tagindex = tagindex % LENGTH(tagicons[DEFAULT_TAGS]); 10 | #if BAR_ALTTAGSDECORATION_PATCH 11 | for (c = m->clients; c && (!(c->tags & 1 << tag) || HIDDEN(c)); c = c->next); 12 | if (c) 13 | return tagicons[ALT_TAGS_DECORATION][tagindex]; 14 | #endif // BAR_ALTTAGSDECORATION_PATCH 15 | #if BAR_ALTERNATIVE_TAGS_PATCH 16 | if (m->alttag) 17 | return tagicons[ALTERNATIVE_TAGS][tagindex]; 18 | #endif // BAR_ALTERNATIVE_TAGS_PATCH 19 | return tagicons[DEFAULT_TAGS][tagindex]; 20 | } -------------------------------------------------------------------------------- /patch/tagall.c: -------------------------------------------------------------------------------- 1 | void 2 | tagall(const Arg *arg) 3 | { 4 | if (!selmon->clients) 5 | return; 6 | /* if parameter starts with F, just move floating windows */ 7 | int floating_only = (char *)arg->v && ((char *)arg->v)[0] == 'F' ? 1 : 0; 8 | int tag = (char *)arg->v ? atoi(((char *)arg->v) + floating_only) : 0; 9 | int j; 10 | Client* c; 11 | if (tag >= 0 && tag < NUMTAGS) 12 | for (c = selmon->clients; c; c = c->next) 13 | { 14 | if (!floating_only || c->isfloating) 15 | for (j = 0; j < NUMTAGS; j++) 16 | { 17 | if (c->tags & 1 << j && selmon->tagset[selmon->seltags] & 1 << j) 18 | { 19 | c->tags = c->tags ^ (1 << j & TAGMASK); 20 | c->tags = c->tags | 1 << (tag-1); 21 | } 22 | } 23 | } 24 | arrange(selmon); 25 | } -------------------------------------------------------------------------------- /patch/reorganizetags.c: -------------------------------------------------------------------------------- 1 | void 2 | reorganizetags(const Arg *arg) 3 | { 4 | Client *c; 5 | unsigned int occ, unocc, i; 6 | unsigned int tagdest[NUMTAGS]; 7 | 8 | occ = 0; 9 | for (c = selmon->clients; c; c = c->next) 10 | occ |= (1 << (ffs(c->tags)-1)); 11 | unocc = 0; 12 | for (i = 0; i < NUMTAGS; ++i) { 13 | while (unocc < i && (occ & (1 << unocc))) 14 | unocc++; 15 | if (occ & (1 << i)) { 16 | tagdest[i] = unocc; 17 | occ &= ~(1 << i); 18 | occ |= 1 << unocc; 19 | } 20 | } 21 | 22 | for (c = selmon->clients; c; c = c->next) 23 | c->tags = 1 << tagdest[ffs(c->tags)-1]; 24 | if (selmon->sel) 25 | selmon->tagset[selmon->seltags] = selmon->sel->tags; 26 | arrange(selmon); 27 | } -------------------------------------------------------------------------------- /patch/cool_autostart.c: -------------------------------------------------------------------------------- 1 | /* dwm will keep pid's of processes from autostart array and kill them at quit */ 2 | static pid_t *autostart_pids; 3 | static size_t autostart_len; 4 | 5 | /* execute command from autostart array */ 6 | static void 7 | autostart_exec() 8 | { 9 | const char *const *p; 10 | size_t i = 0; 11 | 12 | /* count entries */ 13 | for (p = autostart; *p; autostart_len++, p++) 14 | while (*++p); 15 | 16 | autostart_pids = malloc(autostart_len * sizeof(pid_t)); 17 | for (p = autostart; *p; i++, p++) { 18 | if ((autostart_pids[i] = fork()) == 0) { 19 | setsid(); 20 | execvp(*p, (char *const *)p); 21 | fprintf(stderr, "dwm: execvp %s\n", *p); 22 | perror(" failed"); 23 | _exit(EXIT_FAILURE); 24 | } 25 | /* skip arguments */ 26 | while (*++p); 27 | } 28 | } -------------------------------------------------------------------------------- /patch/fakefullscreenclient.c: -------------------------------------------------------------------------------- 1 | void 2 | togglefakefullscreen(const Arg *arg) 3 | { 4 | Client *c = selmon->sel; 5 | if (!c) 6 | return; 7 | 8 | if (c->fakefullscreen) { 9 | if (c->isfullscreen) { 10 | if (c->isfloating && c->fakefullscreen == 1) { 11 | c->oldstate = c->isfloating; 12 | c->oldx = c->x; 13 | c->oldy = c->y; 14 | c->oldw = c->w; 15 | c->oldh = c->h; 16 | } 17 | c->fakefullscreen = 0; 18 | } 19 | else 20 | c->isfullscreen = 0; 21 | } else { 22 | c->fakefullscreen = 1; 23 | if (c->isfullscreen) { 24 | c->isfloating = c->oldstate; 25 | c->bw = c->oldbw; 26 | c->x = c->oldx; 27 | c->y = c->oldy; 28 | c->w = c->oldw; 29 | c->h = c->oldh; 30 | resizeclient(c, c->x, c->y, c->w, c->h); 31 | } 32 | c->isfullscreen = 0; 33 | } 34 | setfullscreen(c, !c->isfullscreen); 35 | } -------------------------------------------------------------------------------- /patch/tagothermonitor.c: -------------------------------------------------------------------------------- 1 | #if IPC_PATCH || DWMC_PATCH 2 | void 3 | tagnextmonex(const Arg *arg) 4 | { 5 | tagnextmon(&((Arg) { .ui = 1 << arg->ui })); 6 | } 7 | 8 | void 9 | tagprevmonex(const Arg *arg) 10 | { 11 | tagprevmon(&((Arg) { .ui = 1 << arg->ui })); 12 | } 13 | #endif // IPC_PATCH | DWMC_PATCH 14 | 15 | void 16 | tagnextmon(const Arg *arg) 17 | { 18 | tagothermon(arg, 1); 19 | } 20 | 21 | void 22 | tagprevmon(const Arg *arg) 23 | { 24 | tagothermon(arg, -1); 25 | } 26 | 27 | void 28 | tagothermon(const Arg *arg, int dir) 29 | { 30 | Client *sel; 31 | Monitor *newmon; 32 | 33 | if (!selmon->sel || !mons->next) 34 | return; 35 | sel = selmon->sel; 36 | newmon = dirtomon(dir); 37 | sendmon(sel, newmon); 38 | if (arg->ui & TAGMASK) { 39 | sel->tags = arg->ui & TAGMASK; 40 | focus(NULL); 41 | arrange(newmon); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /patch/moveplace.c: -------------------------------------------------------------------------------- 1 | void 2 | moveplace(const Arg *arg) 3 | { 4 | Client *c; 5 | int nh, nw, nx, ny; 6 | c = selmon->sel; 7 | if (!c || (arg->ui >= 9)) 8 | return; 9 | if (selmon->lt[selmon->sellt]->arrange && !c->isfloating) 10 | togglefloating(NULL); 11 | nh = (selmon->wh / 3) - (c->bw * 2); 12 | nw = (selmon->ww / 3) - (c->bw * 2); 13 | nx = (arg->ui % 3) -1; 14 | ny = (arg->ui / 3) -1; 15 | if (nx < 0) 16 | nx = selmon->wx; 17 | else if (nx > 0) 18 | nx = selmon->wx + selmon->ww - nw - c->bw*2; 19 | else 20 | nx = selmon->wx + selmon->ww/2 - nw/2 - c->bw; 21 | if (ny <0) 22 | ny = selmon->wy; 23 | else if (ny > 0) 24 | ny = selmon->wy + selmon->wh - nh - c->bw*2; 25 | else 26 | ny = selmon->wy + selmon->wh/2 - nh/2 - c->bw; 27 | resize(c, nx, ny, nw, nh, True); 28 | XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, nw/2, nh/2); 29 | } -------------------------------------------------------------------------------- /patch/push_no_master.c: -------------------------------------------------------------------------------- 1 | Client * 2 | prevt(Client *c) 3 | { 4 | Client *p, *r; 5 | 6 | for (p = selmon->clients, r = NULL; p && p != c; p = p->next) 7 | if (!p->isfloating && ISVISIBLE(p)) 8 | r = p; 9 | return r; 10 | } 11 | 12 | void 13 | pushup(const Arg *arg) 14 | { 15 | Client *sel = selmon->sel, *c; 16 | 17 | if (!sel || sel->isfloating) 18 | return; 19 | if ((c = prevt(sel)) && c != nexttiled(selmon->clients)) { 20 | detach(sel); 21 | sel->next = c; 22 | for (c = selmon->clients; c->next != sel->next; c = c->next); 23 | c->next = sel; 24 | } 25 | focus(sel); 26 | arrange(selmon); 27 | } 28 | 29 | void 30 | pushdown(const Arg *arg) 31 | { 32 | Client *sel = selmon->sel, *c; 33 | 34 | if (!sel || sel->isfloating || sel == nexttiled(selmon->clients)) 35 | return; 36 | if ((c = nexttiled(sel->next))) { 37 | detach(sel); 38 | sel->next = c->next; 39 | c->next = sel; 40 | } 41 | focus(sel); 42 | arrange(selmon); 43 | } -------------------------------------------------------------------------------- /patch/scratchpad.c: -------------------------------------------------------------------------------- 1 | void 2 | togglescratch(const Arg *arg) 3 | { 4 | Client *c = NULL; 5 | Monitor *mon; 6 | unsigned int found = 0; 7 | unsigned int scratchtag = SPTAG(arg->ui); 8 | Arg sparg = {.v = scratchpads[arg->ui].cmd}; 9 | 10 | for (mon = mons; mon && !found; mon = mon->next) 11 | for (c = mon->clients; c && !(found = c->tags & scratchtag); c = c->next); 12 | 13 | if (found) { 14 | if (c->mon != selmon) { 15 | if (c->mon->tagset[c->mon->seltags] & SPTAGMASK) 16 | c->mon->tagset[c->mon->seltags] ^= scratchtag; 17 | sendmon(c, selmon); 18 | } 19 | 20 | unsigned int newtagset = selmon->tagset[selmon->seltags] ^ scratchtag; 21 | if (newtagset) { 22 | selmon->tagset[selmon->seltags] = newtagset; 23 | focus(NULL); 24 | arrange(selmon); 25 | } 26 | if (ISVISIBLE(c)) { 27 | focus(c); 28 | restack(selmon); 29 | } 30 | } else { 31 | selmon->tagset[selmon->seltags] |= scratchtag; 32 | spawn(&sparg); 33 | } 34 | } -------------------------------------------------------------------------------- /patch/shiftviewclients.c: -------------------------------------------------------------------------------- 1 | void 2 | shiftviewclients(const Arg *arg) 3 | { 4 | Arg shifted; 5 | Client *c; 6 | unsigned int tagmask = 0; 7 | 8 | for (c = selmon->clients; c; c = c->next) 9 | #if SCRATCHPADS_PATCH 10 | if (!(c->tags & SPTAGMASK)) 11 | tagmask = tagmask | c->tags; 12 | #elif SCRATCHPAD_ALT_1_PATCH 13 | if (!(c->tags & SCRATCHPAD_MASK)) 14 | tagmask = tagmask | c->tags; 15 | #else 16 | tagmask = tagmask | c->tags; 17 | #endif // SCRATCHPADS_PATCH 18 | 19 | shifted.ui = selmon->tagset[selmon->seltags]; 20 | if (arg->i > 0) // left circular shift 21 | do { 22 | shifted.ui = (shifted.ui << arg->i) 23 | | (shifted.ui >> (NUMTAGS - arg->i)); 24 | } while (tagmask && !(shifted.ui & tagmask)); 25 | else // right circular shift 26 | do { 27 | shifted.ui = (shifted.ui >> (- arg->i) 28 | | shifted.ui << (NUMTAGS + arg->i)); 29 | } while (tagmask && !(shifted.ui & tagmask)); 30 | 31 | view(&shifted); 32 | } -------------------------------------------------------------------------------- /patch/setborderpx.c: -------------------------------------------------------------------------------- 1 | void 2 | setborderpx(const Arg *arg) 3 | { 4 | Client *c; 5 | int prev_borderpx = selmon->borderpx; 6 | 7 | if (arg->i == 0) 8 | selmon->borderpx = borderpx; 9 | else if (selmon->borderpx + arg->i < 0) 10 | selmon->borderpx = 0; 11 | else 12 | selmon->borderpx += arg->i; 13 | 14 | for (c = selmon->clients; c; c = c->next) 15 | { 16 | if (c->bw + arg->i < 0) 17 | c->bw = selmon->borderpx = 0; 18 | else 19 | c->bw = selmon->borderpx; 20 | 21 | if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) 22 | { 23 | if (arg->i != 0) 24 | resize(c, c->x, c->y, c->w-(arg->i*2), c->h-(arg->i*2), 0); 25 | else if (prev_borderpx > borderpx) 26 | resize(c, c->x, c->y, c->w + 2*(prev_borderpx - borderpx), c->h + 2*(prev_borderpx - borderpx), 0); 27 | else if (prev_borderpx < borderpx) 28 | resize(c, c->x, c->y, c->w - 2*(borderpx - prev_borderpx), c->h - 2*(borderpx - prev_borderpx), 0); 29 | } 30 | } 31 | arrange(selmon); 32 | } -------------------------------------------------------------------------------- /layoutmenu.sh: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/bash 2 | # Layoutmenu script for dmenu 3 | 4 | choice=$(cat <<> Floating 8 | []= Tiled 9 | ||| Columns 10 | >M> CFM 11 | [M] Monocle 12 | [D] Deck 13 | TTT Bstack 14 | === BstrackHoriz 15 | ::: Grid 16 | (@) Spiral 17 | |+| Tatami 18 | EOF) 19 | 20 | case $choice in 21 | '[\\] Fibonacci') 22 | printf 0 23 | ;; 24 | 25 | '|M| Centered') 26 | printf 1 27 | ;; 28 | 29 | '><> Floating') 30 | printf 2 31 | ;; 32 | 33 | '[]= Tiled') 34 | printf 3 35 | ;; 36 | 37 | '||| Columns') 38 | printf 4 39 | ;; 40 | 41 | '>M> CFM') 42 | printf 5 43 | ;; 44 | 45 | '[M] Monocle') 46 | printf 6 47 | ;; 48 | 49 | '[D] Deck') 50 | printf 7 51 | ;; 52 | 53 | 'TTT Bstack') 54 | printf 8 55 | ;; 56 | 57 | '=== BstrackHoriz') 58 | printf 9 59 | ;; 60 | 61 | '::: Grid') 62 | printf 10 63 | ;; 64 | 65 | '(@) Spiral') 66 | printf 11 67 | ;; 68 | 69 | '|+| Tatami') 70 | printf 12 71 | ;; 72 | esac 73 | -------------------------------------------------------------------------------- /patch/bar_flexwintitle.h: -------------------------------------------------------------------------------- 1 | static int width_flexwintitle(Bar *bar, BarArg *a); 2 | static int draw_flexwintitle(Bar *bar, BarArg *a); 3 | static int click_flexwintitle(Bar *bar, Arg *arg, BarArg *a); 4 | 5 | static void flextitledraw(Monitor *m, Client *c, int unused, int x, int w, int groupactive, Arg *arg, BarArg *barg); 6 | static void flextitleclick(Monitor *m, Client *c, int passx, int x, int w, int unused, Arg *arg, BarArg *barg); 7 | static int flextitlecalculate(Monitor *m, int offx, int w, int passx, void(*tabfn)(Monitor *, Client *, int, int, int, int, Arg *arg, BarArg *barg), Arg *arg, BarArg *barg); 8 | static int getschemefor(Monitor *m, int group, int activegroup); 9 | static int getselschemefor(int scheme); 10 | static Client *flextitledrawarea(Monitor *m, Client *c, int x, int r, int w, int max_clients, int tabscheme, int draw_tiled, int draw_hidden, int draw_floating, int passx, void(*tabfn)(Monitor *, Client *, int, int, int, int, Arg *arg, BarArg *barg), Arg *arg, BarArg *barg); -------------------------------------------------------------------------------- /patch/bar_holdbar.c: -------------------------------------------------------------------------------- 1 | void 2 | holdbar(const Arg *arg) 3 | { 4 | if (selmon->showbar) 5 | return; 6 | Bar *bar; 7 | selmon->showbar = 2; 8 | updatebarpos(selmon); 9 | for (bar = selmon->bar; bar; bar = bar->next) 10 | XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh); 11 | } 12 | 13 | void 14 | keyrelease(XEvent *e) 15 | { 16 | Bar *bar; 17 | if (XEventsQueued(dpy, QueuedAfterReading)) { 18 | XEvent ne; 19 | XPeekEvent(dpy, &ne); 20 | 21 | if (ne.type == KeyPress && ne.xkey.time == e->xkey.time && 22 | ne.xkey.keycode == e->xkey.keycode) { 23 | XNextEvent(dpy, &ne); 24 | return; 25 | } 26 | } 27 | if (e->xkey.keycode == XKeysymToKeycode(dpy, HOLDKEY) && selmon->showbar == 2) { 28 | selmon->showbar = 0; 29 | updatebarpos(selmon); 30 | for (bar = selmon->bar; bar; bar = bar->next) 31 | XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh); 32 | arrange(selmon); 33 | } 34 | #if COMBO_PATCH 35 | combo = 0; 36 | #endif // COMBO_PATCH 37 | } -------------------------------------------------------------------------------- /patch/rotatestack.c: -------------------------------------------------------------------------------- 1 | void 2 | enqueue(Client *c) 3 | { 4 | Client *l; 5 | for (l = c->mon->clients; l && l->next; l = l->next); 6 | if (l) { 7 | l->next = c; 8 | c->next = NULL; 9 | } 10 | } 11 | 12 | void 13 | enqueuestack(Client *c) 14 | { 15 | Client *l; 16 | for (l = c->mon->stack; l && l->snext; l = l->snext); 17 | if (l) { 18 | l->snext = c; 19 | c->snext = NULL; 20 | } 21 | } 22 | 23 | void 24 | rotatestack(const Arg *arg) 25 | { 26 | Client *c = NULL, *f; 27 | 28 | if (!selmon->sel) 29 | return; 30 | f = selmon->sel; 31 | if (arg->i > 0) { 32 | for (c = nexttiled(selmon->clients); c && nexttiled(c->next); c = nexttiled(c->next)); 33 | if (c){ 34 | detach(c); 35 | attach(c); 36 | detachstack(c); 37 | attachstack(c); 38 | } 39 | } else { 40 | if ((c = nexttiled(selmon->clients))){ 41 | detach(c); 42 | enqueue(c); 43 | detachstack(c); 44 | enqueuestack(c); 45 | } 46 | } 47 | if (c){ 48 | arrange(selmon); 49 | focus(f); 50 | restack(selmon); 51 | } 52 | } -------------------------------------------------------------------------------- /patch/bar_alpha.c: -------------------------------------------------------------------------------- 1 | 2 | static int useargb = 0; 3 | static Visual *visual; 4 | static int depth; 5 | static Colormap cmap; 6 | 7 | void 8 | xinitvisual() 9 | { 10 | XVisualInfo *infos; 11 | XRenderPictFormat *fmt; 12 | int nitems; 13 | int i; 14 | 15 | XVisualInfo tpl = { 16 | .screen = screen, 17 | .depth = 32, 18 | .class = TrueColor 19 | }; 20 | long masks = VisualScreenMask | VisualDepthMask | VisualClassMask; 21 | 22 | infos = XGetVisualInfo(dpy, masks, &tpl, &nitems); 23 | visual = NULL; 24 | for (i = 0; i < nitems; i ++) { 25 | fmt = XRenderFindVisualFormat(dpy, infos[i].visual); 26 | if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) { 27 | visual = infos[i].visual; 28 | depth = infos[i].depth; 29 | cmap = XCreateColormap(dpy, root, visual, AllocNone); 30 | useargb = 1; 31 | break; 32 | } 33 | } 34 | 35 | XFree(infos); 36 | 37 | if (!visual) { 38 | visual = DefaultVisual(dpy, screen); 39 | depth = DefaultDepth(dpy, screen); 40 | cmap = DefaultColormap(dpy, screen); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /transient.c: -------------------------------------------------------------------------------- 1 | /* cc transient.c -o transient -lX11 */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main(void) { 9 | Display *d; 10 | Window r, f, t = None; 11 | XSizeHints h; 12 | XEvent e; 13 | 14 | d = XOpenDisplay(NULL); 15 | if (!d) 16 | exit(1); 17 | r = DefaultRootWindow(d); 18 | 19 | f = XCreateSimpleWindow(d, r, 100, 100, 400, 400, 0, 0, 0); 20 | h.min_width = h.max_width = h.min_height = h.max_height = 400; 21 | h.flags = PMinSize | PMaxSize; 22 | XSetWMNormalHints(d, f, &h); 23 | XStoreName(d, f, "floating"); 24 | XMapWindow(d, f); 25 | 26 | XSelectInput(d, f, ExposureMask); 27 | while (1) { 28 | XNextEvent(d, &e); 29 | 30 | if (t == None) { 31 | sleep(5); 32 | t = XCreateSimpleWindow(d, r, 50, 50, 100, 100, 0, 0, 0); 33 | XSetTransientForHint(d, t, f); 34 | XStoreName(d, t, "transient"); 35 | XMapWindow(d, t); 36 | XSelectInput(d, t, ExposureMask); 37 | } 38 | } 39 | 40 | XCloseDisplay(d); 41 | exit(0); 42 | } 43 | -------------------------------------------------------------------------------- /patch/transfer.c: -------------------------------------------------------------------------------- 1 | void 2 | transfer(const Arg *arg) 3 | { 4 | Client *c, *mtail = selmon->clients, *stail = NULL, *insertafter; 5 | int transfertostack = 0, i, nmasterclients; 6 | 7 | for (i = 0, c = selmon->clients; c; c = c->next) { 8 | if (!ISVISIBLE(c) || c->isfloating) continue; 9 | if (selmon->sel == c) { transfertostack = i < selmon->nmaster && selmon->nmaster != 0; } 10 | if (i < selmon->nmaster) { nmasterclients++; mtail = c; } 11 | stail = c; 12 | i++; 13 | } 14 | if (selmon->sel->isfloating || i == 0) { 15 | return; 16 | } else if (transfertostack) { 17 | selmon->nmaster = MIN(i, selmon->nmaster) - 1; 18 | insertafter = stail; 19 | } else { 20 | selmon->nmaster = selmon->nmaster + 1; 21 | insertafter = mtail; 22 | } 23 | if (insertafter != selmon->sel) { 24 | detach(selmon->sel); 25 | if (selmon->nmaster == 1 && !transfertostack) { 26 | attach(selmon->sel); // Head prepend case 27 | } else { 28 | selmon->sel->next = insertafter->next; 29 | insertafter->next = selmon->sel; 30 | } 31 | } 32 | arrange(selmon); 33 | } -------------------------------------------------------------------------------- /patch/combo.c: -------------------------------------------------------------------------------- 1 | static int combo = 0; 2 | 3 | #if !BAR_HOLDBAR_PATCH 4 | void 5 | keyrelease(XEvent *e) 6 | { 7 | combo = 0; 8 | } 9 | #endif // !BAR_HOLDBAR_PATCH 10 | 11 | void 12 | combotag(const Arg *arg) 13 | { 14 | if (selmon->sel && arg->ui & TAGMASK) { 15 | #if SWITCHTAG_PATCH 16 | if (selmon->sel->switchtag) 17 | selmon->sel->switchtag = 0; 18 | #endif // SWITCHTAG_PATCH 19 | if (combo) { 20 | selmon->sel->tags |= arg->ui & TAGMASK; 21 | } else { 22 | combo = 1; 23 | selmon->sel->tags = arg->ui & TAGMASK; 24 | } 25 | focus(NULL); 26 | arrange(selmon); 27 | } 28 | } 29 | 30 | void 31 | comboview(const Arg *arg) 32 | { 33 | unsigned newtags = arg->ui & TAGMASK; 34 | if (combo) { 35 | selmon->tagset[selmon->seltags] |= newtags; 36 | } else { 37 | selmon->seltags ^= 1; /*toggle tagset*/ 38 | combo = 1; 39 | if (newtags) { 40 | #if PERTAG_PATCH 41 | pertagview(&((Arg) { .ui = newtags })); 42 | #else 43 | selmon->tagset[selmon->seltags] = newtags; 44 | #endif // PERTAG_PATCH 45 | } 46 | } 47 | focus(NULL); 48 | arrange(selmon); 49 | } -------------------------------------------------------------------------------- /patch/vanitygaps.h: -------------------------------------------------------------------------------- 1 | /* Key binding functions */ 2 | static void defaultgaps(const Arg *arg); 3 | static void incrgaps(const Arg *arg); 4 | static void incrigaps(const Arg *arg); 5 | static void incrogaps(const Arg *arg); 6 | static void incrohgaps(const Arg *arg); 7 | static void incrovgaps(const Arg *arg); 8 | static void incrihgaps(const Arg *arg); 9 | static void incrivgaps(const Arg *arg); 10 | static void togglegaps(const Arg *arg); 11 | 12 | /* Internals */ 13 | #if DRAGMFACT_PATCH || CENTEREDMASTER_LAYOUT || CENTEREDFLOATINGMASTER_LAYOUT || COLUMNS_LAYOUT || DECK_LAYOUT || FIBONACCI_DWINDLE_LAYOUT || FIBONACCI_SPIRAL_LAYOUT || GAPPLESSGRID_LAYOUT || NROWGRID_LAYOUT || HORIZGRID_LAYOUT || BSTACK_LAYOUT || BSTACKHORIZ_LAYOUT || GRIDMODE_LAYOUT || FLEXTILE_DELUXE_LAYOUT || TILE_LAYOUT || (VANITYGAPS_MONOCLE_PATCH && MONOCLE_LAYOUT) 14 | static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc); 15 | #endif 16 | static void setgaps(int oh, int ov, int ih, int iv); 17 | #if IPC_PATCH || DWMC_PATCH 18 | static void setgapsex(const Arg *arg); 19 | #endif // IPC_PATCH | DWMC_PATCH -------------------------------------------------------------------------------- /patch/decorationhints.c: -------------------------------------------------------------------------------- 1 | static Atom motifatom; 2 | 3 | void 4 | updatemotifhints(Client *c) 5 | { 6 | Atom real; 7 | int format; 8 | unsigned char *p = NULL; 9 | unsigned long n, extra; 10 | unsigned long *motif; 11 | int width, height; 12 | 13 | if (!decorhints) 14 | return; 15 | 16 | if (XGetWindowProperty(dpy, c->win, motifatom, 0L, 5L, False, motifatom, 17 | &real, &format, &n, &extra, &p) == Success && p != NULL) { 18 | motif = (unsigned long*)p; 19 | if (motif[MWM_HINTS_FLAGS_FIELD] & MWM_HINTS_DECORATIONS) { 20 | width = WIDTH(c); 21 | height = HEIGHT(c); 22 | 23 | if (motif[MWM_HINTS_DECORATIONS_FIELD] & MWM_DECOR_ALL || 24 | motif[MWM_HINTS_DECORATIONS_FIELD] & MWM_DECOR_BORDER || 25 | motif[MWM_HINTS_DECORATIONS_FIELD] & MWM_DECOR_TITLE) 26 | #if SETBORDERPX_PATCH 27 | c->bw = c->oldbw = c->mon->borderpx; 28 | #else 29 | c->bw = c->oldbw = borderpx; 30 | #endif // SETBORDERPX_PATCH 31 | else 32 | c->bw = c->oldbw = 0; 33 | 34 | resize(c, c->x, c->y, width - (2*c->bw), height - (2*c->bw), 0); 35 | } 36 | XFree(p); 37 | } 38 | } -------------------------------------------------------------------------------- /patch/attachx.c: -------------------------------------------------------------------------------- 1 | void 2 | attachx(Client *c) 3 | { 4 | #if ATTACHABOVE_PATCH 5 | Client *at; 6 | if (!(c->mon->sel == NULL || c->mon->sel == c->mon->clients || c->mon->sel->isfloating)) { 7 | for (at = c->mon->clients; at->next != c->mon->sel; at = at->next); 8 | c->next = at->next; 9 | at->next = c; 10 | return; 11 | } 12 | #elif ATTACHASIDE_PATCH 13 | Client *at; 14 | unsigned int n; 15 | 16 | for (at = c->mon->clients, n = 0; at; at = at->next) 17 | if (!at->isfloating && ISVISIBLEONTAG(at, c->tags)) 18 | if (++n >= c->mon->nmaster) 19 | break; 20 | 21 | if (at && c->mon->nmaster) { 22 | c->next = at->next; 23 | at->next = c; 24 | return; 25 | } 26 | #elif ATTACHBELOW_PATCH 27 | if (!(c->mon->sel == NULL || c->mon->sel == c || c->mon->sel->isfloating)) { 28 | c->next = c->mon->sel->next; 29 | c->mon->sel->next = c; 30 | return; 31 | } 32 | #elif ATTACHBOTTOM_PATCH 33 | Client *at; 34 | for (at = c->mon->clients; at && at->next; at = at->next); 35 | if (at) { 36 | at->next = c; 37 | c->next = NULL; 38 | return; 39 | } 40 | #endif 41 | attach(c); // master (default) 42 | } 43 | -------------------------------------------------------------------------------- /patch/layout_monocle.c: -------------------------------------------------------------------------------- 1 | #if VANITYGAPS_PATCH && VANITYGAPS_MONOCLE_PATCH 2 | void 3 | monocle(Monitor *m) 4 | { 5 | unsigned int n; 6 | int oh, ov, ih, iv; 7 | Client *c; 8 | 9 | getgaps(m, &oh, &ov, &ih, &iv, &n); 10 | 11 | #if !MONOCLESYMBOL_PATCH 12 | if (n > 0) /* override layout symbol */ 13 | snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); 14 | #endif // MONOCLESYMBOL_PATCH 15 | for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) 16 | resize(c, m->wx + ov, m->wy + oh, m->ww - 2 * c->bw - 2 * ov, m->wh - 2 * c->bw - 2 * oh, 0); 17 | } 18 | #else 19 | void 20 | monocle(Monitor *m) 21 | { 22 | #if !MONOCLESYMBOL_PATCH 23 | unsigned int n = 0; 24 | #endif // MONOCLESYMBOL_PATCH 25 | Client *c; 26 | 27 | #if !MONOCLESYMBOL_PATCH 28 | for (c = m->clients; c; c = c->next) 29 | if (ISVISIBLE(c)) 30 | n++; 31 | if (n > 0) /* override layout symbol */ 32 | snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); 33 | #endif // MONOCLESYMBOL_PATCH 34 | for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) 35 | resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); 36 | } 37 | #endif // VANITYGAPS_PATCH -------------------------------------------------------------------------------- /patch/xrdb.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define XRDB_LOAD_COLOR(R,V) if (XrmGetResource(xrdb, R, NULL, &type, &value) == True) { \ 4 | if (value.addr != NULL && strnlen(value.addr, 8) == 7 && value.addr[0] == '#') { \ 5 | int i = 1; \ 6 | for (; i <= 6; i++) { \ 7 | if (value.addr[i] < 48) break; \ 8 | if (value.addr[i] > 57 && value.addr[i] < 65) break; \ 9 | if (value.addr[i] > 70 && value.addr[i] < 97) break; \ 10 | if (value.addr[i] > 102) break; \ 11 | } \ 12 | if (i == 7) { \ 13 | strncpy(V, value.addr, 7); \ 14 | V[7] = '\0'; \ 15 | } \ 16 | } \ 17 | } 18 | 19 | static void loadxrdb(void); 20 | static void xrdb(const Arg *arg); 21 | 22 | -------------------------------------------------------------------------------- /patch/bar_wintitle_hidden.c: -------------------------------------------------------------------------------- 1 | int 2 | width_wintitle_hidden(Bar *bar, BarArg *a) 3 | { 4 | return a->w; 5 | } 6 | 7 | int 8 | draw_wintitle_hidden(Bar *bar, BarArg *a) 9 | { 10 | drw_rect(drw, a->x, a->y, a->w, a->h, 1, 1); 11 | return calc_wintitle_hidden(bar->mon, a->x, a->w, -1, flextitledraw, NULL, a); 12 | } 13 | 14 | int 15 | click_wintitle_hidden(Bar *bar, Arg *arg, BarArg *a) 16 | { 17 | calc_wintitle_hidden(bar->mon, 0, a->w, a->x, flextitleclick, arg, a); 18 | return ClkWinTitle; 19 | } 20 | 21 | int 22 | calc_wintitle_hidden( 23 | Monitor *m, int offx, int tabw, int passx, 24 | void(*tabfn)(Monitor *, Client *, int, int, int, int, Arg *arg, BarArg *barg), 25 | Arg *arg, BarArg *barg 26 | ) { 27 | Client *c; 28 | int clientsnhidden = 0, w, r; 29 | int groupactive = GRP_HIDDEN; 30 | 31 | for (c = m->clients; c; c = c->next) { 32 | if (!ISVISIBLE(c)) 33 | continue; 34 | if (HIDDEN(c)) 35 | clientsnhidden++; 36 | } 37 | 38 | if (!clientsnhidden) 39 | return 0; 40 | 41 | w = tabw / clientsnhidden; 42 | r = tabw % clientsnhidden; 43 | c = flextitledrawarea(m, m->clients, offx, r, w, clientsnhidden, SCHEMEFOR(GRP_HIDDEN), 0, 1, 0, passx, tabfn, arg, barg); 44 | return 1; 45 | } -------------------------------------------------------------------------------- /patch/bar_wintitle_floating.c: -------------------------------------------------------------------------------- 1 | int 2 | width_wintitle_floating(Bar *bar, BarArg *a) 3 | { 4 | return a->w; 5 | } 6 | 7 | int 8 | draw_wintitle_floating(Bar *bar, BarArg *a) 9 | { 10 | drw_rect(drw, a->x, a->y, a->w, a->h, 1, 1); 11 | return calc_wintitle_floating(bar->mon, a->x, a->w, -1, flextitledraw, NULL, a); 12 | } 13 | 14 | int 15 | click_wintitle_floating(Bar *bar, Arg *arg, BarArg *a) 16 | { 17 | calc_wintitle_floating(bar->mon, 0, a->w, a->x, flextitleclick, arg, a); 18 | return ClkWinTitle; 19 | } 20 | 21 | int 22 | calc_wintitle_floating( 23 | Monitor *m, int offx, int tabw, int passx, 24 | void(*tabfn)(Monitor *, Client *, int, int, int, int, Arg *arg, BarArg *barg), 25 | Arg *arg, BarArg *barg 26 | ) { 27 | Client *c; 28 | int clientsnfloating = 0, w, r; 29 | int groupactive = GRP_FLOAT; 30 | 31 | for (c = m->clients; c; c = c->next) { 32 | if (!ISVISIBLE(c) || HIDDEN(c)) 33 | continue; 34 | if (c->isfloating) 35 | clientsnfloating++; 36 | } 37 | 38 | if (!clientsnfloating) 39 | return 0; 40 | 41 | w = tabw / clientsnfloating; 42 | r = tabw % clientsnfloating; 43 | c = flextitledrawarea(m, m->clients, offx, r, w, clientsnfloating, SCHEMEFOR(GRP_FLOAT), 0, 0, 1, passx, tabfn, arg, barg); 44 | return 1; 45 | } -------------------------------------------------------------------------------- /patch/fsignal.c: -------------------------------------------------------------------------------- 1 | int 2 | fake_signal(void) 3 | { 4 | char fsignal[256]; 5 | char indicator[9] = "fsignal:"; 6 | char str_signum[16]; 7 | int i, v, signum; 8 | size_t len_fsignal, len_indicator = strlen(indicator); 9 | 10 | // Get root name property 11 | if (gettextprop(root, XA_WM_NAME, fsignal, sizeof(fsignal))) { 12 | len_fsignal = strlen(fsignal); 13 | 14 | // Check if this is indeed a fake signal 15 | if (len_indicator > len_fsignal ? 0 : strncmp(indicator, fsignal, len_indicator) == 0) { 16 | memcpy(str_signum, &fsignal[len_indicator], len_fsignal - len_indicator); 17 | str_signum[len_fsignal - len_indicator] = '\0'; 18 | 19 | // Convert string value into managable integer 20 | for (i = signum = 0; i < strlen(str_signum); i++) { 21 | v = str_signum[i] - '0'; 22 | if (v >= 0 && v <= 9) { 23 | signum = signum * 10 + v; 24 | } 25 | } 26 | 27 | // Check if a signal was found, and if so handle it 28 | if (signum) 29 | for (i = 0; i < LENGTH(signals); i++) 30 | if (signum == signals[i].signum && signals[i].func) 31 | signals[i].func(&(signals[i].arg)); 32 | 33 | // A fake signal was sent 34 | return 1; 35 | } 36 | } 37 | 38 | // No fake signal was sent, so proceed with update 39 | return 0; 40 | } -------------------------------------------------------------------------------- /patch/bar_ewmhtags.c: -------------------------------------------------------------------------------- 1 | void 2 | setcurrentdesktop(void) 3 | { 4 | long data[] = { 0 }; 5 | XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1); 6 | } 7 | 8 | void 9 | setdesktopnames(void) 10 | { 11 | int i; 12 | XTextProperty text; 13 | char *tags[NUMTAGS]; 14 | for (i = 0; i < NUMTAGS; i++) 15 | tags[i] = tagicon(selmon, i); 16 | Xutf8TextListToTextProperty(dpy, tags, NUMTAGS, XUTF8StringStyle, &text); 17 | XSetTextProperty(dpy, root, &text, netatom[NetDesktopNames]); 18 | } 19 | 20 | void 21 | setnumdesktops(void) 22 | { 23 | long data[] = { NUMTAGS }; 24 | XChangeProperty(dpy, root, netatom[NetNumberOfDesktops], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1); 25 | } 26 | 27 | void 28 | setviewport(void) 29 | { 30 | long data[] = { 0, 0 }; 31 | XChangeProperty(dpy, root, netatom[NetDesktopViewport], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 2); 32 | } 33 | 34 | void 35 | updatecurrentdesktop(void) 36 | { 37 | long rawdata[] = { selmon->tagset[selmon->seltags] }; 38 | int i = 0; 39 | while (*rawdata >> (i + 1)) { 40 | i++; 41 | } 42 | long data[] = { i }; 43 | XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1); 44 | } -------------------------------------------------------------------------------- /patch/tagallmon.c: -------------------------------------------------------------------------------- 1 | void 2 | tagallmon(const Arg *arg) 3 | { 4 | Monitor *m; 5 | Client *c, *last, *slast, *next; 6 | 7 | if (!mons->next) 8 | return; 9 | 10 | m = dirtomon(arg->i); 11 | for (last = m->clients; last && last->next; last = last->next); 12 | for (slast = m->stack; slast && slast->snext; slast = slast->snext); 13 | 14 | for (c = selmon->clients; c; c = next) { 15 | next = c->next; 16 | if (!ISVISIBLE(c)) 17 | continue; 18 | unfocus(c, 1, NULL); 19 | detach(c); 20 | detachstack(c); 21 | c->mon = m; 22 | c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ 23 | c->next = NULL; 24 | c->snext = NULL; 25 | if (last) 26 | last = last->next = c; 27 | else 28 | m->clients = last = c; 29 | if (slast) 30 | slast = slast->snext = c; 31 | else 32 | m->stack = slast = c; 33 | if (c->isfullscreen) { 34 | #if !FAKEFULLSCREEN_PATCH && FAKEFULLSCREEN_CLIENT_PATCH 35 | if (c->fakefullscreen != 1) { 36 | resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh); 37 | XRaiseWindow(dpy, c->win); 38 | } 39 | #elif !FAKEFULLSCREEN_PATCH 40 | resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh); 41 | XRaiseWindow(dpy, c->win); 42 | #endif // FAKEFULLSCREEN_CLIENT_PATCH 43 | } 44 | } 45 | 46 | focus(NULL); 47 | arrange(NULL); 48 | } -------------------------------------------------------------------------------- /patch/bar_systray.h: -------------------------------------------------------------------------------- 1 | #define SYSTEM_TRAY_REQUEST_DOCK 0 2 | #define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0 3 | 4 | /* XEMBED messages */ 5 | #define XEMBED_EMBEDDED_NOTIFY 0 6 | #define XEMBED_WINDOW_ACTIVATE 1 7 | #define XEMBED_FOCUS_IN 4 8 | #define XEMBED_MODALITY_ON 10 9 | 10 | #define XEMBED_MAPPED (1 << 0) 11 | #define XEMBED_WINDOW_ACTIVATE 1 12 | #define XEMBED_WINDOW_DEACTIVATE 2 13 | 14 | #define VERSION_MAJOR 0 15 | #define VERSION_MINOR 0 16 | #define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR 17 | 18 | /* enums */ 19 | enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */ 20 | 21 | typedef struct Systray Systray; 22 | struct Systray { 23 | Window win; 24 | Client *icons; 25 | Bar *bar; 26 | }; 27 | 28 | /* bar integration */ 29 | static int width_systray(Bar *bar, BarArg *a); 30 | static int draw_systray(Bar *bar, BarArg *a); 31 | static int click_systray(Bar *bar, Arg *arg, BarArg *a); 32 | 33 | /* function declarations */ 34 | static Atom getatomprop(Client *c, Atom prop); 35 | static void removesystrayicon(Client *i); 36 | static void resizerequest(XEvent *e); 37 | static void updatesystrayicongeom(Client *i, int w, int h); 38 | static void updatesystrayiconstate(Client *i, XPropertyEvent *ev); 39 | static Client *wintosystrayicon(Window w); 40 | 41 | -------------------------------------------------------------------------------- /patch/movestack.c: -------------------------------------------------------------------------------- 1 | void 2 | movestack(const Arg *arg) 3 | { 4 | Client *c = NULL, *p = NULL, *pc = NULL, *i; 5 | if (arg->i > 0) { 6 | if (!selmon->sel) 7 | return; 8 | /* find the client after selmon->sel */ 9 | for (c = selmon->sel->next; c && (!ISVISIBLE(c) || c->isfloating); c = c->next); 10 | if (!c) 11 | for (c = selmon->clients; c && (!ISVISIBLE(c) || c->isfloating); c = c->next); 12 | } 13 | else { 14 | /* find the client before selmon->sel */ 15 | for (i = selmon->clients; i != selmon->sel; i = i->next) 16 | if(ISVISIBLE(i) && !i->isfloating) 17 | c = i; 18 | if (!c) 19 | for (; i; i = i->next) 20 | if (ISVISIBLE(i) && !i->isfloating) 21 | c = i; 22 | } 23 | 24 | /* find the client before selmon->sel and c */ 25 | for (i = selmon->clients; i && (!p || !pc); i = i->next) { 26 | if (i->next == selmon->sel) 27 | p = i; 28 | if (i->next == c) 29 | pc = i; 30 | } 31 | 32 | /* swap c and selmon->sel selmon->clients in the selmon->clients list */ 33 | if (c && c != selmon->sel) { 34 | Client *temp = selmon->sel->next==c?selmon->sel:selmon->sel->next; 35 | selmon->sel->next = c->next==selmon->sel?c:c->next; 36 | c->next = temp; 37 | 38 | if (p && p != c) 39 | p->next = c; 40 | if (pc && pc != selmon->sel) 41 | pc->next = selmon->sel; 42 | 43 | if (selmon->sel == selmon->clients) 44 | selmon->clients = c; 45 | else if (c == selmon->clients) 46 | selmon->clients = selmon->sel; 47 | 48 | arrange(selmon); 49 | } 50 | } -------------------------------------------------------------------------------- /patch/ipc/IPCClient.c: -------------------------------------------------------------------------------- 1 | #include "IPCClient.h" 2 | 3 | #include 4 | #include 5 | 6 | #include "util.h" 7 | 8 | IPCClient * 9 | ipc_client_new(int fd) 10 | { 11 | IPCClient *c = (IPCClient *)malloc(sizeof(IPCClient)); 12 | 13 | if (c == NULL) return NULL; 14 | 15 | // Initialize struct 16 | memset(&c->event, 0, sizeof(struct epoll_event)); 17 | 18 | c->buffer_size = 0; 19 | c->buffer = NULL; 20 | c->fd = fd; 21 | c->event.data.fd = fd; 22 | c->next = NULL; 23 | c->prev = NULL; 24 | c->subscriptions = 0; 25 | 26 | return c; 27 | } 28 | 29 | void 30 | ipc_list_add_client(IPCClientList *list, IPCClient *nc) 31 | { 32 | DEBUG("Adding client with fd %d to list\n", nc->fd); 33 | 34 | if (*list == NULL) { 35 | // List is empty, point list at first client 36 | *list = nc; 37 | } else { 38 | IPCClient *c; 39 | // Go to last client in list 40 | for (c = *list; c && c->next; c = c->next) 41 | ; 42 | c->next = nc; 43 | nc->prev = c; 44 | } 45 | } 46 | 47 | void 48 | ipc_list_remove_client(IPCClientList *list, IPCClient *c) 49 | { 50 | IPCClient *cprev = c->prev; 51 | IPCClient *cnext = c->next; 52 | 53 | if (cprev != NULL) cprev->next = c->next; 54 | if (cnext != NULL) cnext->prev = c->prev; 55 | if (c == *list) *list = c->next; 56 | } 57 | 58 | IPCClient * 59 | ipc_list_get_client(IPCClientList list, int fd) 60 | { 61 | for (IPCClient *c = list; c; c = c->next) { 62 | if (c->fd == fd) return c; 63 | } 64 | 65 | return NULL; 66 | } 67 | -------------------------------------------------------------------------------- /patch/push.c: -------------------------------------------------------------------------------- 1 | static Client * 2 | nextc(Client *c, float f) 3 | { 4 | if (!f) 5 | return nexttiled(c); 6 | 7 | for (; c && !ISVISIBLE(c); c = c->next); 8 | return c; 9 | } 10 | 11 | static Client * 12 | prevc(Client *c, float f) 13 | { 14 | Client *p, *r; 15 | 16 | for (p = selmon->clients, r = NULL; c && p && p != c; p = p->next) 17 | if ((f || !p->isfloating) && ISVISIBLE(p)) 18 | r = p; 19 | return r; 20 | } 21 | 22 | static void 23 | pushup(const Arg *arg) 24 | { 25 | Client *sel = selmon->sel; 26 | Client *c; 27 | 28 | if (!sel || (sel->isfloating && !arg->f)) 29 | return; 30 | if ((c = prevc(sel, arg->f))) { 31 | /* attach before c */ 32 | detach(sel); 33 | sel->next = c; 34 | if (selmon->clients == c) 35 | selmon->clients = sel; 36 | else { 37 | for (c = selmon->clients; c->next != sel->next; c = c->next); 38 | c->next = sel; 39 | } 40 | } else { 41 | /* move to the end */ 42 | for (c = sel; c->next; c = c->next); 43 | detach(sel); 44 | sel->next = NULL; 45 | c->next = sel; 46 | } 47 | focus(sel); 48 | arrange(selmon); 49 | } 50 | 51 | static void 52 | pushdown(const Arg *arg) 53 | { 54 | Client *sel = selmon->sel; 55 | Client *c; 56 | 57 | if (!sel || (sel->isfloating && !arg->f)) 58 | return; 59 | if ((c = nextc(sel->next, arg->f))) { 60 | /* attach after c */ 61 | detach(sel); 62 | sel->next = c->next; 63 | c->next = sel; 64 | } else { 65 | /* move to the front */ 66 | detach(sel); 67 | attach(sel); 68 | } 69 | focus(sel); 70 | arrange(selmon); 71 | } -------------------------------------------------------------------------------- /patch/roundedcorners.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void drawroundedcorners(Client *c) 4 | { 5 | if (corner_radius <= 0 || !c || c->isfullscreen) 6 | return; 7 | 8 | Window win; 9 | win = c->win; 10 | if (!win) 11 | return; 12 | 13 | XWindowAttributes win_attr; 14 | if (!XGetWindowAttributes(dpy, win, &win_attr)) 15 | return; 16 | 17 | int dia = 2 * corner_radius; 18 | int w = c->w; 19 | int h = c->h; 20 | if (w < dia || h < dia) 21 | return; 22 | 23 | Pixmap mask; 24 | mask = XCreatePixmap(dpy, win, w, h, 1); 25 | if (!mask) 26 | return; 27 | 28 | XGCValues xgcv; 29 | GC shape_gc; 30 | shape_gc = XCreateGC(dpy, mask, 0, &xgcv); 31 | 32 | if (!shape_gc) { 33 | XFreePixmap(dpy, mask); 34 | free(shape_gc); 35 | return; 36 | } 37 | 38 | XSetForeground(dpy, shape_gc, 0); 39 | XFillRectangle(dpy, mask, shape_gc, 0, 0, w, h); 40 | XSetForeground(dpy, shape_gc, 1); 41 | XFillArc(dpy, mask, shape_gc, 0, 0, dia, dia, 0, 23040); 42 | XFillArc(dpy, mask, shape_gc, w-dia-1, 0, dia, dia, 0, 23040); 43 | XFillArc(dpy, mask, shape_gc, 0, h-dia-1, dia, dia, 0, 23040); 44 | XFillArc(dpy, mask, shape_gc, w-dia-1, h-dia-1, dia, dia, 0, 23040); 45 | XFillRectangle(dpy, mask, shape_gc, corner_radius, 0, w-dia, h); 46 | XFillRectangle(dpy, mask, shape_gc, 0, corner_radius, w, h-dia); 47 | XShapeCombineMask(dpy, win, ShapeBounding, 0, 0, mask, ShapeSet); 48 | XFreePixmap(dpy, mask); 49 | XFreeGC(dpy, shape_gc); 50 | } -------------------------------------------------------------------------------- /patch/bar_wintitle.c: -------------------------------------------------------------------------------- 1 | int 2 | width_wintitle(Bar *bar, BarArg *a) 3 | { 4 | return a->w; 5 | } 6 | 7 | int 8 | draw_wintitle(Bar *bar, BarArg *a) 9 | { 10 | #if BAR_TITLE_LEFT_PAD_PATCH && BAR_TITLE_RIGHT_PAD_PATCH 11 | int x = a->x + lrpad / 2, w = a->w - lrpad; 12 | #elif BAR_TITLE_LEFT_PAD_PATCH 13 | int x = a->x + lrpad / 2, w = a->w - lrpad / 2; 14 | #elif BAR_TITLE_RIGHT_PAD_PATCH 15 | int x = a->x, w = a->w - lrpad / 2; 16 | #else 17 | int x = a->x, w = a->w; 18 | #endif // BAR_TITLE_LEFT_PAD_PATCH | BAR_TITLE_RIGHT_PAD_PATCH 19 | Monitor *m = bar->mon; 20 | int pad = lrpad / 2; 21 | 22 | if (!m->sel) { 23 | drw_setscheme(drw, scheme[SchemeTitleNorm]); 24 | drw_rect(drw, x, a->y, w, a->h, 1, 1); 25 | return 0; 26 | } 27 | 28 | drw_setscheme(drw, scheme[m == selmon ? SchemeTitleSel : SchemeTitleNorm]); 29 | #if BAR_IGNORE_XFT_ERRORS_WHEN_DRAWING_TEXT_PATCH 30 | XSetErrorHandler(xerrordummy); 31 | #endif // BAR_IGNORE_XFT_ERRORS_WHEN_DRAWING_TEXT_PATCH 32 | #if BAR_CENTEREDWINDOWNAME_PATCH 33 | if (TEXTW(m->sel->name) < w) 34 | pad = (w - TEXTW(m->sel->name) + lrpad) / 2; 35 | #endif // BAR_CENTEREDWINDOWNAME_PATCH 36 | drw_text(drw, x, a->y, w, a->h, pad, m->sel->name, 0, False); 37 | #if BAR_IGNORE_XFT_ERRORS_WHEN_DRAWING_TEXT_PATCH 38 | XSync(dpy, False); 39 | XSetErrorHandler(xerror); 40 | #endif // BAR_IGNORE_XFT_ERRORS_WHEN_DRAWING_TEXT_PATCH 41 | drawstateindicator(m, m->sel, 1, x, a->y, w, a->h, 0, 0, m->sel->isfixed); 42 | return 1; 43 | } 44 | 45 | int 46 | click_wintitle(Bar *bar, Arg *arg, BarArg *a) 47 | { 48 | return ClkWinTitle; 49 | } 50 | 51 | 52 | -------------------------------------------------------------------------------- /patch/selfrestart.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | /** 8 | * Magically finds the current's executable path 9 | * 10 | * I'm doing the do{}while(); trick because Linux (what I'm running) is not 11 | * POSIX compilant and so lstat() cannot be trusted on /proc entries 12 | * 13 | * @return char* the path of the current executable 14 | */ 15 | char *get_dwm_path() 16 | { 17 | struct stat s; 18 | int r, length, rate = 42; 19 | char *path = NULL; 20 | 21 | if (lstat("/proc/self/exe", &s) == -1) { 22 | perror("lstat:"); 23 | return NULL; 24 | } 25 | 26 | length = s.st_size + 1 - rate; 27 | 28 | do 29 | { 30 | length+=rate; 31 | 32 | free(path); 33 | path = malloc(sizeof(char) * length); 34 | 35 | if (path == NULL){ 36 | perror("malloc:"); 37 | return NULL; 38 | } 39 | 40 | r = readlink("/proc/self/exe", path, length); 41 | 42 | if (r == -1){ 43 | perror("readlink:"); 44 | return NULL; 45 | } 46 | } while (r >= length); 47 | 48 | path[r] = '\0'; 49 | 50 | return path; 51 | } 52 | 53 | /** 54 | * self-restart 55 | * 56 | * Initially inspired by: Yu-Jie Lin 57 | * https://sites.google.com/site/yjlnotes/notes/dwm 58 | */ 59 | void self_restart(const Arg *arg) 60 | { 61 | char *const argv[] = {get_dwm_path(), NULL}; 62 | 63 | if (argv[0] == NULL) { 64 | return; 65 | } 66 | 67 | execv(argv[0], argv); 68 | } 69 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | /* ___ ______________ _ ____ ___ 2 | * | \/ | _ | _ | | | | \/ | 3 | * | . . | | | | | | | | | | . . | 4 | * | |\/| | | | | | | | |/\| | |\/| | 5 | * | | | \ \_/ | |/ /\ /\ | | | | 6 | * \_| |_/\___/|___/ \/ \/\_| |_/ 7 | * 8 | * MODWM - Modular Dynamic Window Manager. 9 | * --------------------------------------- 10 | * / 11 | 12 | MODWM is an extremely fast, small, and dynamic window manager for X. 13 | 14 | 15 | Requirements 16 | ------------ 17 | In order to build MODWM you need the Xlib header files. 18 | 19 | 20 | Installation 21 | ------------ 22 | Edit config.mk to match your local setup (dwm is installed into 23 | the /usr/local namespace by default). 24 | 25 | Afterwards enter the following command to build and install dwm (if 26 | necessary as root): 27 | 28 | make clean install 29 | 30 | 31 | Running modwm 32 | ----------- 33 | Add the following line to your .xinitrc to start dwm using startx: 34 | 35 | exec dwm 36 | 37 | In order to connect dwm to a specific display, make sure that 38 | the DISPLAY environment variable is set correctly, e.g.: 39 | 40 | DISPLAY=foo.bar:1 exec dwm 41 | 42 | (This will start dwm on display :1 of the host foo.bar.) 43 | 44 | In order to display status info in the bar, you can do something 45 | like this in your .xinitrc: 46 | 47 | while xsetroot -name "`date` `uptime | sed 's/.*,//'`" 48 | do 49 | sleep 1 50 | done & 51 | exec dwm 52 | 53 | 54 | Configuration 55 | ------------- 56 | The configuration of dwm is done by creating a custom config.h 57 | and (re)compiling the source code. 58 | -------------------------------------------------------------------------------- /patch/ipc/IPCClient.h: -------------------------------------------------------------------------------- 1 | #ifndef IPC_CLIENT_H_ 2 | #define IPC_CLIENT_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | typedef struct IPCClient IPCClient; 9 | /** 10 | * This structure contains the details of an IPC Client and pointers for a 11 | * linked list 12 | */ 13 | struct IPCClient { 14 | int fd; 15 | int subscriptions; 16 | 17 | char *buffer; 18 | uint32_t buffer_size; 19 | 20 | struct epoll_event event; 21 | IPCClient *next; 22 | IPCClient *prev; 23 | }; 24 | 25 | typedef IPCClient *IPCClientList; 26 | 27 | /** 28 | * Allocate memory for new IPCClient with the specified file descriptor and 29 | * initialize struct. 30 | * 31 | * @param fd File descriptor of IPC client 32 | * 33 | * @return Address to allocated IPCClient struct 34 | */ 35 | IPCClient *ipc_client_new(int fd); 36 | 37 | /** 38 | * Add an IPC Client to the specified list 39 | * 40 | * @param list Address of the list to add the client to 41 | * @param nc Address of the IPCClient 42 | */ 43 | void ipc_list_add_client(IPCClientList *list, IPCClient *nc); 44 | 45 | /** 46 | * Remove an IPCClient from the specified list 47 | * 48 | * @param list Address of the list to remove the client from 49 | * @param c Address of the IPCClient 50 | */ 51 | void ipc_list_remove_client(IPCClientList *list, IPCClient *c); 52 | 53 | /** 54 | * Get an IPCClient from the specified IPCClient list 55 | * 56 | * @param list List to remove the client from 57 | * @param fd File descriptor of the IPCClient 58 | */ 59 | IPCClient *ipc_list_get_client(IPCClientList list, int fd); 60 | 61 | #endif // IPC_CLIENT_H_ 62 | -------------------------------------------------------------------------------- /patch/inplacerotate.c: -------------------------------------------------------------------------------- 1 | void 2 | insertclient(Client *item, Client *insertItem, int after) 3 | { 4 | Client *c; 5 | if (item == NULL || insertItem == NULL || item == insertItem) return; 6 | detach(insertItem); 7 | if (!after && selmon->clients == item) { 8 | attach(insertItem); 9 | return; 10 | } 11 | if (after) { 12 | c = item; 13 | } else { 14 | for (c = selmon->clients; c; c = c->next) { if (c->next == item) break; } 15 | } 16 | insertItem->next = c->next; 17 | c->next = insertItem; 18 | } 19 | 20 | void 21 | inplacerotate(const Arg *arg) 22 | { 23 | if (!selmon->sel || (selmon->sel->isfloating && !arg->f)) return; 24 | 25 | unsigned int selidx = 0, i = 0; 26 | Client *c = NULL, *stail = NULL, *mhead = NULL, *mtail = NULL, *shead = NULL; 27 | 28 | // Shift client 29 | for (c = selmon->clients; c; c = c->next) { 30 | if (ISVISIBLE(c) && !(c->isfloating)) { 31 | if (selmon->sel == c) { selidx = i; } 32 | if (i == selmon->nmaster - 1) { mtail = c; } 33 | if (i == selmon->nmaster) { shead = c; } 34 | if (mhead == NULL) { mhead = c; } 35 | stail = c; 36 | i++; 37 | } 38 | } 39 | if (arg->i < 0 && selidx >= selmon->nmaster) insertclient(stail, shead, 1); 40 | if (arg->i > 0 && selidx >= selmon->nmaster) insertclient(shead, stail, 0); 41 | if (arg->i < 0 && selidx < selmon->nmaster) insertclient(mtail, mhead, 1); 42 | if (arg->i > 0 && selidx < selmon->nmaster) insertclient(mhead, mtail, 0); 43 | 44 | // Restore focus position 45 | i = 0; 46 | for (c = selmon->clients; c; c = c->next) { 47 | if (!ISVISIBLE(c) || (c->isfloating)) continue; 48 | if (i == selidx) { focus(c); break; } 49 | i++; 50 | } 51 | arrange(selmon); 52 | focus(c); 53 | } -------------------------------------------------------------------------------- /patch/layout_facts.c: -------------------------------------------------------------------------------- 1 | #if CFACTS_PATCH 2 | void 3 | getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr) 4 | { 5 | unsigned int n; 6 | float mfacts = 0, sfacts = 0; 7 | int mtotal = 0, stotal = 0; 8 | Client *c; 9 | 10 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) 11 | if (n < m->nmaster) 12 | mfacts += c->cfact; 13 | else 14 | sfacts += c->cfact; 15 | 16 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) 17 | if (n < m->nmaster) 18 | mtotal += msize * (c->cfact / mfacts); 19 | else 20 | stotal += ssize * (c->cfact / sfacts); 21 | 22 | *mf = mfacts; // total factor of master area 23 | *sf = sfacts; // total factor of stack area 24 | *mr = msize - mtotal; // the remainder (rest) of pixels after a cfacts master split 25 | *sr = ssize - stotal; // the remainder (rest) of pixels after a cfacts stack split 26 | } 27 | #else 28 | void 29 | getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr) 30 | { 31 | unsigned int n; 32 | float mfacts, sfacts; 33 | int mtotal = 0, stotal = 0; 34 | Client *c; 35 | 36 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 37 | mfacts = MIN(n, m->nmaster); 38 | sfacts = n - m->nmaster; 39 | 40 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) 41 | if (n < m->nmaster) 42 | mtotal += msize / mfacts; 43 | else 44 | stotal += ssize / sfacts; 45 | 46 | *mf = mfacts; // total factor of master area 47 | *sf = sfacts; // total factor of stack area 48 | *mr = msize - mtotal; // the remainder (rest) of pixels after an even master split 49 | *sr = ssize - stotal; // the remainder (rest) of pixels after an even stack split 50 | } 51 | #endif // CFACTS_PATCH 52 | -------------------------------------------------------------------------------- /patch/bar_fancybar.c: -------------------------------------------------------------------------------- 1 | int 2 | width_fancybar(Bar *bar, BarArg *a) 3 | { 4 | return a->w; 5 | } 6 | 7 | int 8 | draw_fancybar(Bar *bar, BarArg *a) 9 | { 10 | int ftw, mw, ew = 0, n = 0; 11 | unsigned int i; 12 | Client *c; 13 | Monitor *m = bar->mon; 14 | 15 | #if BAR_TITLE_LEFT_PAD && BAR_TITLE_RIGHT_PAD 16 | int x = a->x + lrpad / 2, w = a->w - lrpad; 17 | #elif BAR_TITLE_LEFT_PAD 18 | int x = a->x + lrpad / 2, w = a->w - lrpad / 2; 19 | #elif BAR_TITLE_RIGHT_PAD 20 | int x = a->x, w = a->w - lrpad / 2; 21 | #else 22 | int x = a->x, w = a->w; 23 | #endif // BAR_TITLE_LEFT_PAD | BAR_TITLE_RIGHT_PAD 24 | 25 | for (c = m->clients; c; c = c->next) { 26 | if (ISVISIBLE(c)) 27 | n++; 28 | } 29 | 30 | if (n > 0) { 31 | ftw = TEXTW(m->sel->name); 32 | mw = (ftw >= w || n == 1) ? 0 : (w - ftw) / (n - 1); 33 | 34 | i = 0; 35 | 36 | for (c = m->clients; c; c = c->next) { 37 | if (!ISVISIBLE(c) || c == m->sel) 38 | continue; 39 | ftw = TEXTW(c->name); 40 | if (ftw < mw) 41 | ew += (mw - ftw); 42 | else 43 | i++; 44 | } 45 | 46 | if (i > 0) 47 | mw += ew / i; 48 | 49 | for (c = m->clients; c; c = c->next) { 50 | if (!ISVISIBLE(c)) 51 | continue; 52 | ftw = MIN(m->sel == c ? w : mw, TEXTW(c->name)); 53 | drw_setscheme(drw, scheme[m->sel == c ? SchemeTitleSel : SchemeTitleNorm]); 54 | if (ftw > 0) /* trap special handling of 0 in drw_text */ 55 | drw_text(drw, x, a->y, ftw, a->h, lrpad / 2, c->name, 0, False); 56 | if (c->isfloating) 57 | drawindicator(c->mon, c, 1, x, a->y, w, a->h, 0, 0, c->isfixed, floatindicatortype); 58 | x += ftw; 59 | w -= ftw; 60 | } 61 | } 62 | return n; 63 | } 64 | 65 | int 66 | click_fancybar(Bar *bar, Arg *arg, BarArg *a) 67 | { 68 | return ClkWinTitle; 69 | } 70 | 71 | 72 | -------------------------------------------------------------------------------- /patch/bar_vtcolors.c: -------------------------------------------------------------------------------- 1 | void 2 | get_vt_colors(void) 3 | { 4 | char *cfs[3] = { 5 | "/sys/module/vt/parameters/default_red", 6 | "/sys/module/vt/parameters/default_grn", 7 | "/sys/module/vt/parameters/default_blu", 8 | }; 9 | char vtcs[16][8]; 10 | char tk[] = ","; 11 | char cl[64]; 12 | char *tp = NULL; 13 | FILE *fp; 14 | size_t r; 15 | int i, c, n, len; 16 | for (i = 0; i < 16; i++) 17 | strcpy(vtcs[i], "#000000"); 18 | 19 | for (i = 0, r = 0; i < 3; i++) { 20 | if ((fp = fopen(cfs[i], "r")) == NULL) 21 | continue; 22 | while ((cl[r] = fgetc(fp)) != EOF && cl[r] != '\n') 23 | r++; 24 | cl[r] = '\0'; 25 | for (c = 0, tp = cl, n = 0; c < 16; c++, tp++) { 26 | if ((r = strcspn(tp, tk)) == -1) 27 | break; 28 | for (n = 0; r && *tp >= 48 && *tp < 58; r--, tp++) 29 | n = n * 10 - 48 + *tp; 30 | vtcs[c][i * 2 + 1] = n / 16 < 10 ? n / 16 + 48 : n / 16 + 87; 31 | vtcs[c][i * 2 + 2] = n % 16 < 10 ? n % 16 + 48 : n % 16 + 87; 32 | } 33 | fclose(fp); 34 | } 35 | 36 | len = LENGTH(colors); 37 | if (len > LENGTH(color_ptrs)) 38 | len = LENGTH(color_ptrs); 39 | for (i = 0; i < len; i++) { 40 | for (c = 0; c < ColCount; c++) { 41 | n = color_ptrs[i][c]; 42 | if (n > -1 && strlen(colors[i][c]) >= strlen(vtcs[n])) 43 | memcpy(colors[i][c], vtcs[n], 7); 44 | } 45 | } 46 | } 47 | 48 | int get_luminance(char *r) 49 | { 50 | char *c = r; 51 | int n[3] = {0}; 52 | int i = 0; 53 | 54 | while (*c) { 55 | if (*c >= 48 && *c < 58) 56 | n[i / 2] = n[i / 2] * 16 - 48 + *c; 57 | else if (*c >= 65 && *c < 71) 58 | n[i / 2] = n[i / 2] * 16 - 55 + *c; 59 | else if (*c >= 97 && *c < 103) 60 | n[i / 2] = n[i / 2] * 16 - 87 + *c; 61 | else 62 | i--; 63 | i++; 64 | c++; 65 | } 66 | 67 | return (0.299 * n[0] + 0.587 * n[1] + 0.114 * n[2]) / 2.55; 68 | } -------------------------------------------------------------------------------- /patch/bar_statuscmd.c: -------------------------------------------------------------------------------- 1 | #if !BAR_DWMBLOCKS_PATCH 2 | static const char statusexport[] = "export BUTTON=-;"; 3 | static int statuscmdn; 4 | static int lastbutton; 5 | #endif // BAR_DWMBLOCKS_PATCH 6 | 7 | int 8 | click_statuscmd(Bar *bar, Arg *arg, BarArg *a) 9 | { 10 | return click_statuscmd_text(arg, a->x, rawstext); 11 | } 12 | 13 | #if BAR_EXTRASTATUS_PATCH 14 | int 15 | click_statuscmd_es(Bar *bar, Arg *arg, BarArg *a) 16 | { 17 | return click_statuscmd_text(arg, a->x, rawestext); 18 | } 19 | #endif // BAR_EXTRASTATUS_PATCH 20 | 21 | int 22 | click_statuscmd_text(Arg *arg, int rel_x, char *text) 23 | { 24 | int i = -1; 25 | int x = 0; 26 | char ch; 27 | #if BAR_DWMBLOCKS_PATCH 28 | dwmblockssig = -1; 29 | #else 30 | statuscmdn = 0; 31 | #endif // BAR_DWMBLOCKS_PATCH 32 | while (text[++i]) { 33 | if ((unsigned char)text[i] < ' ') { 34 | ch = text[i]; 35 | text[i] = '\0'; 36 | #if BAR_STATUS2D_PATCH && !BAR_BAR_STATUSCOLORS_PATCH 37 | x += status2dtextlength(text); 38 | #else 39 | x += TEXTWM(text) - lrpad; 40 | #endif // BAR_STATUS2D_PATCH 41 | text[i] = ch; 42 | text += i+1; 43 | i = -1; 44 | #if BAR_DWMBLOCKS_PATCH 45 | if (x >= rel_x && dwmblockssig != -1) 46 | break; 47 | dwmblockssig = ch; 48 | #else 49 | if (x >= rel_x) 50 | break; 51 | if (ch <= LENGTH(statuscmds)) 52 | statuscmdn = ch - 1; 53 | #endif // BAR_DWMBLOCKS_PATCH 54 | } 55 | } 56 | #if BAR_DWMBLOCKS_PATCH 57 | if (dwmblockssig == -1) 58 | dwmblockssig = 0; 59 | #endif // BAR_DWMBLOCKS_PATCH 60 | return ClkStatusText; 61 | } 62 | 63 | void 64 | copyvalidchars(char *text, char *rawtext) 65 | { 66 | int i = -1, j = 0; 67 | 68 | while (rawtext[++i]) { 69 | if ((unsigned char)rawtext[i] >= ' ') { 70 | text[j++] = rawtext[i]; 71 | } 72 | } 73 | text[j] = '\0'; 74 | } 75 | -------------------------------------------------------------------------------- /patch/stacker.c: -------------------------------------------------------------------------------- 1 | void 2 | focusstack(const Arg *arg) 3 | { 4 | int i = stackpos(arg); 5 | Client *c, *p; 6 | 7 | if (i < 0) 8 | return; 9 | 10 | #if ALWAYSFULLSCREEN_PATCH 11 | if (!selmon->sel || selmon->sel->isfullscreen) 12 | return; 13 | #endif // ALWAYSFULLSCREEN_PATCH 14 | 15 | for (p = NULL, c = selmon->clients; c && (i || !ISVISIBLE(c)); 16 | i -= ISVISIBLE(c) ? 1 : 0, p = c, c = c->next); 17 | focus(c ? c : p); 18 | restack(selmon); 19 | } 20 | 21 | void 22 | pushstack(const Arg *arg) 23 | { 24 | int i = stackpos(arg); 25 | Client *sel = selmon->sel, *c, *p; 26 | 27 | if (i < 0) 28 | return; 29 | else if (i == 0) { 30 | detach(sel); 31 | attach(sel); 32 | } 33 | else { 34 | for (p = NULL, c = selmon->clients; c; p = c, c = c->next) 35 | if (!(i -= (ISVISIBLE(c) && c != sel))) 36 | break; 37 | c = c ? c : p; 38 | detach(sel); 39 | sel->next = c->next; 40 | c->next = sel; 41 | } 42 | arrange(selmon); 43 | } 44 | 45 | int 46 | stackpos(const Arg *arg) 47 | { 48 | int n, i; 49 | Client *c, *l; 50 | 51 | if (!selmon->clients) 52 | return -1; 53 | 54 | if (arg->i == PREVSEL) { 55 | for (l = selmon->stack; l && (!ISVISIBLE(l) || l == selmon->sel); l = l->snext); 56 | if (!l) 57 | return -1; 58 | for (i = 0, c = selmon->clients; c != l; i += ISVISIBLE(c) ? 1 : 0, c = c->next); 59 | return i; 60 | } 61 | else if (ISINC(arg->i)) { 62 | if (!selmon->sel) 63 | return -1; 64 | for (i = 0, c = selmon->clients; c != selmon->sel; i += ISVISIBLE(c) ? 1 : 0, c = c->next); 65 | for (n = i; c; n += ISVISIBLE(c) ? 1 : 0, c = c->next); 66 | return MOD(i + GETINC(arg->i), n); 67 | } 68 | else if (arg->i < 0) { 69 | for (i = 0, c = selmon->clients; c; i += ISVISIBLE(c) ? 1 : 0, c = c->next); 70 | return MAX(i + arg->i, 0); 71 | } 72 | else 73 | return arg->i; 74 | } 75 | -------------------------------------------------------------------------------- /patch/layout_deck.c: -------------------------------------------------------------------------------- 1 | static void 2 | deck(Monitor *m) 3 | { 4 | unsigned int i, n; 5 | int mx = 0, my = 0, mh = 0, mw = 0; 6 | int sx = 0, sy = 0, sh = 0, sw = 0; 7 | float mfacts, sfacts; 8 | int mrest, srest; 9 | Client *c; 10 | 11 | #if VANITYGAPS_PATCH 12 | int oh, ov, ih, iv; 13 | getgaps(m, &oh, &ov, &ih, &iv, &n); 14 | #else 15 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 16 | #endif // VANITYGAPS_PATCH 17 | 18 | if (n == 0) 19 | return; 20 | 21 | #if VANITYGAPS_PATCH 22 | sx = mx = m->wx + ov; 23 | sy = my = m->wy + oh; 24 | sh = mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1); 25 | sw = mw = m->ww - 2*ov; 26 | 27 | if (m->nmaster && n > m->nmaster) { 28 | sw = (mw - iv) * (1 - m->mfact); 29 | mw = (mw - iv) * m->mfact; 30 | sx = mx + mw + iv; 31 | sh = m->wh - 2*oh; 32 | } 33 | #else 34 | sx = mx = m->wx; 35 | sy = my = m->wy; 36 | sh = mh = m->wh; 37 | sw = mw = m->ww; 38 | 39 | if (m->nmaster && n > m->nmaster) { 40 | sw = mw * (1 - m->mfact); 41 | mw = mw * m->mfact; 42 | sx = mx + mw; 43 | } 44 | #endif // VANITYGAPS_PATCH 45 | 46 | getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest); 47 | 48 | if (n - m->nmaster > 0) /* override layout symbol */ 49 | snprintf(m->ltsymbol, sizeof m->ltsymbol, "D %d", n - m->nmaster); 50 | 51 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 52 | if (i < m->nmaster) { 53 | #if CFACTS_PATCH 54 | resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) * c->cfact + (i < mrest ? 1 : 0) - (2*c->bw), 0); 55 | #else 56 | resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); 57 | #endif // CFACTS_PATCH 58 | #if VANITYGAPS_PATCH 59 | my += HEIGHT(c) + ih; 60 | #else 61 | my += HEIGHT(c); 62 | #endif 63 | } else { 64 | resize(c, sx, sy, sw - (2*c->bw), sh - (2*c->bw), 0); 65 | } 66 | } -------------------------------------------------------------------------------- /colors.h: -------------------------------------------------------------------------------- 1 | static char normfgcolor[] = "#FABD2F"; 2 | static char normbgcolor[] = "#322F2E"; 3 | static char normbordercolor[] = "#4C4541"; 4 | static char normfloatcolor[] = "#3A3A3A"; 5 | static char selfgcolor[] = "#E2D0A8"; 6 | static char selbgcolor[] = "#322F2E"; 7 | static char selbordercolor[] = "#665C54"; 8 | static char selfloatcolor[] = "#FABD2F"; 9 | 10 | static char titlenormfgcolor[] = "#D3869B"; 11 | static char titlenormbgcolor[] = "#322F2E"; 12 | static char titlenormbordercolor[] = "#444444"; 13 | static char titlenormfloatcolor[] = "#db8fd9"; 14 | 15 | static char titleselfgcolor[] = "#D5C4A1"; 16 | static char titleselbgcolor[] = "#322F2E"; 17 | static char titleselbordercolor[] = "#005577"; 18 | static char titleselfloatcolor[] = "#005577"; 19 | 20 | static char tagsnormfgcolor[] = "#D5C4A1"; 21 | static char tagsnormbgcolor[] = "#322F2E"; 22 | static char tagsnormbordercolor[] = "#444444"; 23 | static char tagsnormfloatcolor[] = "#db8fd9"; 24 | 25 | static char tagsselfgcolor[] = "#8EC07C"; 26 | static char tagsselbgcolor[] = "#4C4541"; 27 | static char tagsselbordercolor[] = "#FABD2F"; 28 | static char tagsselfloatcolor[] = "#FABD2F"; 29 | 30 | static char hidfgcolor[] = "#FABD2F"; 31 | static char hidbgcolor[] = "#222222"; 32 | static char hidbordercolor[] = "#FABD2F"; 33 | static char hidfloatcolor[] = "#f76e0c"; 34 | 35 | static char urgfgcolor[] = "#D3869B"; 36 | static char urgbgcolor[] = "#4C4541"; 37 | static char urgbordercolor[] = "#FB4934"; 38 | static char urgfloatcolor[] = "#db8fd9"; 39 | 40 | -------------------------------------------------------------------------------- /patch/moveresize.c: -------------------------------------------------------------------------------- 1 | void 2 | moveresize(const Arg *arg) { 3 | /* only floating windows can be moved */ 4 | Client *c; 5 | c = selmon->sel; 6 | int x, y, w, h, nx, ny, nw, nh, ox, oy, ow, oh; 7 | char xAbs, yAbs, wAbs, hAbs; 8 | int msx, msy, dx, dy, nmx, nmy; 9 | unsigned int dui; 10 | Window dummy; 11 | 12 | if (!c || !arg) 13 | return; 14 | if (selmon->lt[selmon->sellt]->arrange && !c->isfloating) 15 | return; 16 | if (sscanf((char *)arg->v, "%d%c %d%c %d%c %d%c", &x, &xAbs, &y, &yAbs, &w, &wAbs, &h, &hAbs) != 8) 17 | return; 18 | 19 | /* compute new window position; prevent window from be positioned outside the current monitor */ 20 | nw = c->w + w; 21 | if (wAbs == 'W') 22 | nw = w < selmon->mw - 2 * c->bw ? w : selmon->mw - 2 * c->bw; 23 | 24 | nh = c->h + h; 25 | if (hAbs == 'H') 26 | nh = h < selmon->mh - 2 * c->bw ? h : selmon->mh - 2 * c->bw; 27 | 28 | nx = c->x + x; 29 | if (xAbs == 'X') { 30 | if (x < selmon->mx) 31 | nx = selmon->mx; 32 | else if (x > selmon->mx + selmon->mw) 33 | nx = selmon->mx + selmon->mw - nw - 2 * c->bw; 34 | else 35 | nx = x; 36 | } 37 | 38 | ny = c->y + y; 39 | if (yAbs == 'Y') { 40 | if (y < selmon->my) 41 | ny = selmon->my; 42 | else if (y > selmon->my + selmon->mh) 43 | ny = selmon->my + selmon->mh - nh - 2 * c->bw; 44 | else 45 | ny = y; 46 | } 47 | 48 | ox = c->x; 49 | oy = c->y; 50 | ow = c->w; 51 | oh = c->h; 52 | 53 | XRaiseWindow(dpy, c->win); 54 | Bool xqp = XQueryPointer(dpy, root, &dummy, &dummy, &msx, &msy, &dx, &dy, &dui); 55 | resize(c, nx, ny, nw, nh, True); 56 | 57 | /* move cursor along with the window to avoid problems caused by the sloppy focus */ 58 | if (xqp && ox <= msx && (ox + ow) >= msx && oy <= msy && (oy + oh) >= msy) 59 | { 60 | nmx = c->x - ox + c->w - ow; 61 | nmy = c->y - oy + c->h - oh; 62 | XWarpPointer(dpy, None, None, 0, 0, 0, 0, nmx, nmy); 63 | } 64 | } -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # MODWM - Modular Dynamic Window Manager. 2 | # --------------------------------------- 3 | # See LICENSE file for copyright and license details. 4 | 5 | include config.mk 6 | 7 | SRC = drw.c dwm.c util.c 8 | OBJ = ${SRC:.c=.o} 9 | 10 | # FreeBSD users, prefix all ifdef, else and endif statements with . for this to work (e.g. .ifdef) 11 | 12 | .ifdef YAJLLIBS 13 | all: options dwm dwm-msg 14 | .else 15 | all: options dwm 16 | .endif 17 | 18 | options: 19 | @echo dwm build options: 20 | @echo "CFLAGS = ${CFLAGS}" 21 | @echo "LDFLAGS = ${LDFLAGS}" 22 | @echo "CC = ${CC}" 23 | 24 | .c.o: 25 | ${CC} -c ${CFLAGS} $< 26 | 27 | ${OBJ}: config.h config.mk patches.h 28 | 29 | config.h: 30 | cp config.def.h $@ 31 | 32 | patches.h: 33 | cp patches.def.h $@ 34 | 35 | dwm: ${OBJ} 36 | ${CC} -o $@ ${OBJ} ${LDFLAGS} 37 | 38 | .ifdef YAJLLIBS 39 | dwm-msg: 40 | ${CC} -o $@ patch/ipc/dwm-msg.c ${LDFLAGS} 41 | .endif 42 | 43 | clean: 44 | rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz 45 | rm -f dwm-msg 46 | 47 | dist: clean 48 | mkdir -p dwm-${VERSION} 49 | cp -R LICENSE Makefile README config.def.h config.mk\ 50 | dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION} 51 | tar -cf dwm-${VERSION}.tar dwm-${VERSION} 52 | gzip dwm-${VERSION}.tar 53 | rm -rf dwm-${VERSION} 54 | 55 | install: all 56 | mkdir -p ${DESTDIR}${PREFIX}/bin 57 | cp -f dwm ${DESTDIR}${PREFIX}/bin 58 | .ifdef YAJLLIBS 59 | cp -f dwm-msg ${DESTDIR}${PREFIX}/bin 60 | .endif 61 | #cp -f patch/dwmc ${DESTDIR}${PREFIX}/bin 62 | chmod 755 ${DESTDIR}${PREFIX}/bin/dwm 63 | .ifdef YAJLLIBS 64 | chmod 755 ${DESTDIR}${PREFIX}/bin/dwm-msg 65 | .endif 66 | mkdir -p ${DESTDIR}${MANPREFIX}/man1 67 | sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1 68 | chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1 69 | 70 | uninstall: 71 | rm -f ${DESTDIR}${PREFIX}/bin/dwm\ 72 | ${DESTDIR}${MANPREFIX}/man1/dwm.1 73 | .PHONY: all options clean dist install uninstall 74 | -------------------------------------------------------------------------------- /patch/tagswapmon.c: -------------------------------------------------------------------------------- 1 | void 2 | tagswapmon(const Arg *arg) 3 | { 4 | Monitor *m; 5 | Client *c, *sc = NULL, *mc = NULL, *next; 6 | 7 | if (!mons->next) 8 | return; 9 | 10 | m = dirtomon(arg->i); 11 | 12 | for (c = selmon->clients; c; c = next) { 13 | next = c->next; 14 | if (!ISVISIBLE(c)) 15 | continue; 16 | unfocus(c, 1, NULL); 17 | detach(c); 18 | detachstack(c); 19 | c->next = sc; 20 | sc = c; 21 | } 22 | 23 | for (c = m->clients; c; c = next) { 24 | next = c->next; 25 | if (!ISVISIBLE(c)) 26 | continue; 27 | unfocus(c, 1, NULL); 28 | detach(c); 29 | detachstack(c); 30 | c->next = mc; 31 | mc = c; 32 | } 33 | 34 | for (c = sc; c; c = next) { 35 | next = c->next; 36 | c->mon = m; 37 | c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ 38 | attach(c); 39 | attachstack(c); 40 | if (c->isfullscreen) { 41 | #if !FAKEFULLSCREEN_PATCH && FAKEFULLSCREEN_CLIENT_PATCH 42 | if (c->fakefullscreen != 1) { 43 | resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh); 44 | XRaiseWindow(dpy, c->win); 45 | } 46 | #elif !FAKEFULLSCREEN_PATCH 47 | resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh); 48 | XRaiseWindow(dpy, c->win); 49 | #endif // FAKEFULLSCREEN_CLIENT_PATCH 50 | } 51 | } 52 | 53 | for (c = mc; c; c = next) { 54 | next = c->next; 55 | c->mon = selmon; 56 | c->tags = selmon->tagset[selmon->seltags]; /* assign tags of target monitor */ 57 | attach(c); 58 | attachstack(c); 59 | if (c->isfullscreen) { 60 | #if !FAKEFULLSCREEN_PATCH && FAKEFULLSCREEN_CLIENT_PATCH 61 | if (c->fakefullscreen != 1) { 62 | resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh); 63 | XRaiseWindow(dpy, c->win); 64 | } 65 | #elif !FAKEFULLSCREEN_PATCH 66 | resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh); 67 | XRaiseWindow(dpy, c->win); 68 | #endif // FAKEFULLSCREEN_CLIENT_PATCH 69 | } 70 | } 71 | 72 | focus(NULL); 73 | arrange(NULL); 74 | } -------------------------------------------------------------------------------- /patch/maximize.c: -------------------------------------------------------------------------------- 1 | void 2 | maximize(int x, int y, int w, int h) 3 | { 4 | XEvent ev; 5 | 6 | if (!selmon->sel || selmon->sel->isfixed) 7 | return; 8 | XRaiseWindow(dpy, selmon->sel->win); 9 | if (!selmon->sel->ismax) { 10 | if (!selmon->lt[selmon->sellt]->arrange || selmon->sel->isfloating) 11 | selmon->sel->wasfloating = True; 12 | else { 13 | togglefloating(NULL); 14 | selmon->sel->wasfloating = False; 15 | } 16 | selmon->sel->oldx = selmon->sel->x; 17 | selmon->sel->oldy = selmon->sel->y; 18 | selmon->sel->oldw = selmon->sel->w; 19 | selmon->sel->oldh = selmon->sel->h; 20 | resize(selmon->sel, x, y, w, h, True); 21 | selmon->sel->ismax = True; 22 | } 23 | else { 24 | resize(selmon->sel, selmon->sel->oldx, selmon->sel->oldy, selmon->sel->oldw, selmon->sel->oldh, True); 25 | if (!selmon->sel->wasfloating) 26 | togglefloating(NULL); 27 | selmon->sel->ismax = False; 28 | } 29 | drawbar(selmon); 30 | while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); 31 | } 32 | 33 | #if SETBORDERPX_PATCH 34 | void 35 | togglemax(const Arg *arg) 36 | { 37 | maximize(selmon->wx, selmon->wy, selmon->ww - 2 * selmon->borderpx, selmon->wh - 2 * selmon->borderpx); 38 | } 39 | 40 | void 41 | toggleverticalmax(const Arg *arg) 42 | { 43 | maximize(selmon->sel->x, selmon->wy, selmon->sel->w, selmon->wh - 2 * selmon->borderpx); 44 | } 45 | 46 | void 47 | togglehorizontalmax(const Arg *arg) 48 | { 49 | maximize(selmon->wx, selmon->sel->y, selmon->ww - 2 * selmon->borderpx, selmon->sel->h); 50 | } 51 | #else 52 | void 53 | togglemax(const Arg *arg) 54 | { 55 | maximize(selmon->wx, selmon->wy, selmon->ww - 2 * borderpx, selmon->wh - 2 * borderpx); 56 | } 57 | 58 | void 59 | toggleverticalmax(const Arg *arg) 60 | { 61 | maximize(selmon->sel->x, selmon->wy, selmon->sel->w, selmon->wh - 2 * borderpx); 62 | } 63 | 64 | void 65 | togglehorizontalmax(const Arg *arg) 66 | { 67 | maximize(selmon->wx, selmon->sel->y, selmon->ww - 2 * borderpx, selmon->sel->h); 68 | } 69 | #endif // SETBORDERPX_PATCH -------------------------------------------------------------------------------- /patch/layout_grid.c: -------------------------------------------------------------------------------- 1 | #if VANITYGAPS_PATCH 2 | void 3 | grid(Monitor *m) 4 | { 5 | unsigned int i, n; 6 | int cx, cy, cw, ch, cc, cr, chrest, cwrest, cols, rows; 7 | int oh, ov, ih, iv; 8 | Client *c; 9 | 10 | getgaps(m, &oh, &ov, &ih, &iv, &n); 11 | 12 | /* grid dimensions */ 13 | for (rows = 0; rows <= n/2; rows++) 14 | if (rows*rows >= n) 15 | break; 16 | cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows; 17 | 18 | /* window geoms (cell height/width) */ 19 | ch = (m->wh - 2*oh - ih * (rows - 1)) / (rows ? rows : 1); 20 | cw = (m->ww - 2*ov - iv * (cols - 1)) / (cols ? cols : 1); 21 | chrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows; 22 | cwrest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols; 23 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { 24 | cc = i / rows; 25 | cr = i % rows; 26 | cx = m->wx + ov + cc * (cw + iv) + MIN(cc, cwrest); 27 | cy = m->wy + oh + cr * (ch + ih) + MIN(cr, chrest); 28 | resize(c, cx, cy, cw + (cc < cwrest ? 1 : 0) - 2*c->bw, ch + (cr < chrest ? 1 : 0) - 2*c->bw, False); 29 | } 30 | } 31 | #else 32 | void 33 | grid(Monitor *m) 34 | { 35 | unsigned int i, n; 36 | int cx, cy, cw, ch, cc, cr, chrest, cwrest, cols, rows; 37 | Client *c; 38 | 39 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 40 | 41 | /* grid dimensions */ 42 | for (rows = 0; rows <= n/2; rows++) 43 | if (rows*rows >= n) 44 | break; 45 | cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows; 46 | 47 | /* window geoms (cell height/width) */ 48 | ch = m->wh / (rows ? rows : 1); 49 | cw = m->ww / (cols ? cols : 1); 50 | chrest = m->wh - ch * rows; 51 | cwrest = m->ww - cw * cols; 52 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { 53 | cc = i / rows; 54 | cr = i % rows; 55 | cx = m->wx + cc * cw + MIN(cc, cwrest); 56 | cy = m->wy + cr * ch + MIN(cr, chrest); 57 | resize(c, cx, cy, cw + (cc < cwrest ? 1 : 0) - 2*c->bw, ch + (cr < chrest ? 1 : 0) - 2*c->bw, False); 58 | } 59 | } 60 | #endif -------------------------------------------------------------------------------- /patch/bar_wintitleactions.c: -------------------------------------------------------------------------------- 1 | void 2 | hide(Client *c) { 3 | 4 | Client *n; 5 | if (!c || HIDDEN(c)) 6 | return; 7 | 8 | Window w = c->win; 9 | static XWindowAttributes ra, ca; 10 | 11 | // more or less taken directly from blackbox's hide() function 12 | XGrabServer(dpy); 13 | XGetWindowAttributes(dpy, root, &ra); 14 | XGetWindowAttributes(dpy, w, &ca); 15 | // prevent UnmapNotify events 16 | XSelectInput(dpy, root, ra.your_event_mask & ~SubstructureNotifyMask); 17 | XSelectInput(dpy, w, ca.your_event_mask & ~StructureNotifyMask); 18 | XUnmapWindow(dpy, w); 19 | setclientstate(c, IconicState); 20 | XSelectInput(dpy, root, ra.your_event_mask); 21 | XSelectInput(dpy, w, ca.your_event_mask); 22 | XUngrabServer(dpy); 23 | 24 | if (c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) { 25 | for (n = c->snext; n && (!ISVISIBLE(n) || HIDDEN(n)); n = n->snext); 26 | if (!n) 27 | for (n = c->mon->stack; n && (!ISVISIBLE(n) || HIDDEN(n)); n = n->snext); 28 | } else { 29 | n = nexttiled(c); 30 | if (!n) 31 | n = prevtiled(c); 32 | } 33 | focus(n); 34 | arrange(c->mon); 35 | } 36 | 37 | void 38 | show(Client *c) 39 | { 40 | if (!c || !HIDDEN(c)) 41 | return; 42 | 43 | XMapWindow(dpy, c->win); 44 | setclientstate(c, NormalState); 45 | arrange(c->mon); 46 | } 47 | 48 | void 49 | togglewin(const Arg *arg) 50 | { 51 | Client *c = (Client*)arg->v; 52 | if (!c) 53 | return; 54 | if (c == selmon->sel) 55 | hide(c); 56 | else { 57 | if (HIDDEN(c)) 58 | show(c); 59 | focus(c); 60 | restack(c->mon); 61 | } 62 | } 63 | 64 | Client * 65 | prevtiled(Client *c) 66 | { 67 | Client *p, *i; 68 | for (p = NULL, i = c->mon->clients; c && i != c; i = i->next) 69 | if (ISVISIBLE(i) && !HIDDEN(i)) 70 | p = i; 71 | return p; 72 | } 73 | 74 | void 75 | showhideclient(const Arg *arg) 76 | { 77 | Client *c = (Client*)arg->v; 78 | if (!c) 79 | c = selmon->sel; 80 | if (!c) 81 | return; 82 | 83 | if (HIDDEN(c)) { 84 | show(c); 85 | focus(c); 86 | restack(c->mon); 87 | } else { 88 | hide(c); 89 | } 90 | } -------------------------------------------------------------------------------- /patch/bar_awesomebar.c: -------------------------------------------------------------------------------- 1 | int 2 | width_awesomebar(Bar *bar, BarArg *a) 3 | { 4 | return a->w; 5 | } 6 | 7 | int 8 | draw_awesomebar(Bar *bar, BarArg *a) 9 | { 10 | int n = 0, scm, remainder = 0, tabw, pad; 11 | unsigned int i; 12 | #if BAR_TITLE_LEFT_PAD && BAR_TITLE_RIGHT_PAD 13 | int x = a->x + lrpad / 2, w = a->w - lrpad; 14 | #elif BAR_TITLE_LEFT_PAD 15 | int x = a->x + lrpad / 2, w = a->w - lrpad / 2; 16 | #elif BAR_TITLE_RIGHT_PAD 17 | int x = a->x, w = a->w - lrpad / 2; 18 | #else 19 | int x = a->x, w = a->w; 20 | #endif // BAR_TITLE_LEFT_PAD | BAR_TITLE_RIGHT_PAD 21 | 22 | Client *c; 23 | for (c = bar->mon->clients; c; c = c->next) 24 | if (ISVISIBLE(c)) 25 | n++; 26 | 27 | if (n > 0) { 28 | remainder = w % n; 29 | tabw = w / n; 30 | for (i = 0, c = bar->mon->clients; c; c = c->next, i++) { 31 | if (!ISVISIBLE(c)) 32 | continue; 33 | if (bar->mon->sel == c) 34 | scm = SchemeTitleSel; 35 | else if (HIDDEN(c)) 36 | scm = SchemeHid; 37 | else 38 | scm = SchemeTitleNorm; 39 | 40 | pad = lrpad / 2; 41 | #if BAR_CENTEREDWINDOWNAME_PATCH 42 | if (TEXTW(c->name) < tabw) 43 | pad = (tabw - TEXTW(c->name) + lrpad) / 2; 44 | #endif // BAR_CENTEREDWINDOWNAME_PATCH 45 | 46 | drw_setscheme(drw, scheme[scm]); 47 | drw_text(drw, x, a->y, tabw + (i < remainder ? 1 : 0), a->h, pad, c->name, 0, False); 48 | if (c->isfloating) 49 | drawindicator(c->mon, c, 1, x, a->y, w, a->h, 0, 0, c->isfixed, floatindicatortype); 50 | x += tabw + (i < remainder ? 1 : 0); 51 | } 52 | } 53 | return n; 54 | } 55 | 56 | int 57 | click_awesomebar(Bar *bar, Arg *arg, BarArg *a) 58 | { 59 | int x = 0, n = 0; 60 | Client *c; 61 | 62 | for (c = bar->mon->clients; c; c = c->next) 63 | if (ISVISIBLE(c)) 64 | n++; 65 | 66 | c = bar->mon->clients; 67 | 68 | do { 69 | if (!c || !ISVISIBLE(c)) 70 | continue; 71 | else 72 | x += (1.0 / (double)n) * a->w; 73 | } while (c && a->x > x && (c = c->next)); 74 | 75 | if (c) { 76 | arg->v = c; 77 | return ClkWinTitle; 78 | } 79 | return -1; 80 | } 81 | -------------------------------------------------------------------------------- /patch/dragcfact.c: -------------------------------------------------------------------------------- 1 | void 2 | dragcfact(const Arg *arg) 3 | { 4 | int prev_x, prev_y, dist_x, dist_y; 5 | float fact; 6 | Client *c; 7 | XEvent ev; 8 | Time lasttime = 0; 9 | 10 | if (!(c = selmon->sel)) 11 | return; 12 | if (c->isfloating) { 13 | resizemouse(arg); 14 | return; 15 | } 16 | #if !FAKEFULLSCREEN_PATCH 17 | #if FAKEFULLSCREEN_CLIENT_PATCH 18 | if (c->isfullscreen && !c->fakefullscreen) /* no support resizing fullscreen windows by mouse */ 19 | return; 20 | #else 21 | if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */ 22 | return; 23 | #endif // FAKEFULLSCREEN_CLIENT_PATCH 24 | #endif // !FAKEFULLSCREEN_PATCH 25 | restack(selmon); 26 | 27 | if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, 28 | None, cursor[CurIronCross]->cursor, CurrentTime) != GrabSuccess) 29 | return; 30 | XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2); 31 | 32 | prev_x = prev_y = -999999; 33 | 34 | do { 35 | XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); 36 | switch(ev.type) { 37 | case ConfigureRequest: 38 | case Expose: 39 | case MapRequest: 40 | handler[ev.type](&ev); 41 | break; 42 | case MotionNotify: 43 | if ((ev.xmotion.time - lasttime) <= (1000 / 60)) 44 | continue; 45 | lasttime = ev.xmotion.time; 46 | if (prev_x == -999999) { 47 | prev_x = ev.xmotion.x_root; 48 | prev_y = ev.xmotion.y_root; 49 | } 50 | 51 | dist_x = ev.xmotion.x - prev_x; 52 | dist_y = ev.xmotion.y - prev_y; 53 | 54 | if (abs(dist_x) > abs(dist_y)) { 55 | fact = (float) 4.0 * dist_x / c->mon->ww; 56 | } else { 57 | fact = (float) -4.0 * dist_y / c->mon->wh; 58 | } 59 | 60 | if (fact) 61 | setcfact(&((Arg) { .f = fact })); 62 | 63 | prev_x = ev.xmotion.x; 64 | prev_y = ev.xmotion.y; 65 | break; 66 | } 67 | } while (ev.type != ButtonRelease); 68 | 69 | 70 | XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2); 71 | 72 | XUngrabPointer(dpy, CurrentTime); 73 | while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); 74 | } -------------------------------------------------------------------------------- /patch/scratchpad_alt_1.c: -------------------------------------------------------------------------------- 1 | static Client * scratchpad_last_showed = NULL; 2 | 3 | static void scratchpad_hide () 4 | { 5 | if (selmon->sel) 6 | { 7 | selmon->sel->tags = SCRATCHPAD_MASK; 8 | focus(NULL); 9 | arrange(selmon); 10 | } 11 | } 12 | 13 | static _Bool scratchpad_last_showed_is_killed (void) 14 | { 15 | _Bool killed = 1; 16 | for (Client * c = selmon->clients; c != NULL; c = c->next) 17 | { 18 | if (c == scratchpad_last_showed) 19 | { 20 | killed = 0; 21 | break; 22 | } 23 | } 24 | return killed; 25 | } 26 | 27 | static void scratchpad_remove () 28 | { 29 | if (selmon->sel && scratchpad_last_showed != NULL && selmon->sel == scratchpad_last_showed) 30 | scratchpad_last_showed = NULL; 31 | } 32 | 33 | static void scratchpad_show () 34 | { 35 | if (scratchpad_last_showed == NULL || scratchpad_last_showed_is_killed ()) 36 | scratchpad_show_first (); 37 | else 38 | { 39 | if (scratchpad_last_showed->tags != SCRATCHPAD_MASK) 40 | { 41 | scratchpad_last_showed->tags = SCRATCHPAD_MASK; 42 | focus(NULL); 43 | arrange(selmon); 44 | } 45 | else 46 | { 47 | _Bool found_current = 0; 48 | _Bool found_next = 0; 49 | for (Client * c = selmon->clients; c != NULL; c = c->next) 50 | { 51 | if (found_current == 0) 52 | { 53 | if (c == scratchpad_last_showed) 54 | { 55 | found_current = 1; 56 | continue; 57 | } 58 | } 59 | else 60 | { 61 | if (c->tags == SCRATCHPAD_MASK) 62 | { 63 | found_next = 1; 64 | scratchpad_show_client (c); 65 | break; 66 | } 67 | } 68 | } 69 | if (found_next == 0) scratchpad_show_first (); 70 | } 71 | } 72 | } 73 | 74 | static void scratchpad_show_client (Client * c) 75 | { 76 | scratchpad_last_showed = c; 77 | c->tags = selmon->tagset[selmon->seltags]; 78 | focus(c); 79 | arrange(selmon); 80 | } 81 | 82 | static void scratchpad_show_first (void) 83 | { 84 | for (Client * c = selmon->clients; c != NULL; c = c->next) 85 | { 86 | if (c->tags == SCRATCHPAD_MASK) 87 | { 88 | scratchpad_show_client (c); 89 | break; 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT/X Consortium License 2 | 3 | © 2006-2019 Anselm R Garbe 4 | © 2006-2009 Jukka Salmi 5 | © 2006-2007 Sander van Dijk 6 | © 2007-2011 Peter Hartlich 7 | © 2007-2009 Szabolcs Nagy 8 | © 2007-2009 Christof Musik 9 | © 2007-2009 Premysl Hruby 10 | © 2007-2008 Enno Gottox Boland 11 | © 2008 Martin Hurton 12 | © 2008 Neale Pickett 13 | © 2009 Mate Nagy 14 | © 2010-2016 Hiltjo Posthuma 15 | © 2010-2012 Connor Lane Smith 16 | © 2011 Christoph Lohmann <20h@r-36.net> 17 | © 2015-2016 Quentin Rameau 18 | © 2015-2016 Eric Pruitt 19 | © 2016-2017 Markus Teich 20 | © 2020-2021 Chris Garvin 21 | 22 | Permission is hereby granted, free of charge, to any person obtaining a 23 | copy of this software and associated documentation files (the "Software"), 24 | to deal in the Software without restriction, including without limitation 25 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 26 | and/or sell copies of the Software, and to permit persons to whom the 27 | Software is furnished to do so, subject to the following conditions: 28 | 29 | The above copyright notice and this permission notice shall be included in 30 | all copies or substantial portions of the Software. 31 | 32 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 33 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 34 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 35 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 36 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 37 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 38 | DEALINGS IN THE SOFTWARE. 39 | -------------------------------------------------------------------------------- /patch/layout_tile.c: -------------------------------------------------------------------------------- 1 | static void 2 | tile(Monitor *m) 3 | { 4 | unsigned int i, n; 5 | int mx = 0, my = 0, mh = 0, mw = 0; 6 | int sx = 0, sy = 0, sh = 0, sw = 0; 7 | float mfacts, sfacts; 8 | int mrest, srest; 9 | Client *c; 10 | 11 | 12 | #if VANITYGAPS_PATCH 13 | int oh, ov, ih, iv; 14 | getgaps(m, &oh, &ov, &ih, &iv, &n); 15 | #else 16 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 17 | #endif // VANITYGAPS_PATCH 18 | 19 | if (n == 0) 20 | return; 21 | 22 | #if VANITYGAPS_PATCH 23 | sx = mx = m->wx + ov; 24 | sy = my = m->wy + oh; 25 | mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1); 26 | sh = m->wh - 2*oh - ih * (n - m->nmaster - 1); 27 | sw = mw = m->ww - 2*ov; 28 | 29 | if (m->nmaster && n > m->nmaster) { 30 | sw = (mw - iv) * (1 - m->mfact); 31 | mw = (mw - iv) * m->mfact; 32 | sx = mx + mw + iv; 33 | } 34 | #else 35 | sx = mx = m->wx; 36 | sy = my = m->wy; 37 | sh = mh = m->wh; 38 | sw = mw = m->ww; 39 | 40 | if (m->nmaster && n > m->nmaster) { 41 | sw = mw * (1 - m->mfact); 42 | mw = mw * m->mfact; 43 | sx = mx + mw; 44 | } 45 | #endif // VANITYGAPS_PATCH 46 | 47 | getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest); 48 | 49 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 50 | if (i < m->nmaster) { 51 | #if CFACTS_PATCH 52 | resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) * c->cfact + (i < mrest ? 1 : 0) - (2*c->bw), 0); 53 | #else 54 | resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); 55 | #endif // CFACTS_PATCH 56 | #if VANITYGAPS_PATCH 57 | my += HEIGHT(c) + ih; 58 | #else 59 | my += HEIGHT(c); 60 | #endif 61 | } else { 62 | #if CFACTS_PATCH 63 | resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) * c->cfact + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0); 64 | #else 65 | resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0); 66 | #endif // CFACTS_PATCH 67 | #if VANITYGAPS_PATCH 68 | sy += HEIGHT(c) + ih; 69 | #else 70 | sy += HEIGHT(c); 71 | #endif 72 | } 73 | } -------------------------------------------------------------------------------- /patch/layout_bstack.c: -------------------------------------------------------------------------------- 1 | static void 2 | bstack(Monitor *m) 3 | { 4 | unsigned int i, n; 5 | int mx = 0, my = 0, mh = 0, mw = 0; 6 | int sx = 0, sy = 0, sh = 0, sw = 0; 7 | float mfacts, sfacts; 8 | int mrest, srest; 9 | Client *c; 10 | 11 | #if VANITYGAPS_PATCH 12 | int oh, ov, ih, iv; 13 | getgaps(m, &oh, &ov, &ih, &iv, &n); 14 | #else 15 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 16 | #endif // VANITYGAPS_PATCH 17 | 18 | if (n == 0) 19 | return; 20 | 21 | #if VANITYGAPS_PATCH 22 | sx = mx = m->wx + ov; 23 | sy = my = m->wy + oh; 24 | sh = mh = m->wh - 2*oh; 25 | mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1); 26 | sw = m->ww - 2*ov - iv * (n - m->nmaster - 1); 27 | 28 | if (m->nmaster && n > m->nmaster) { 29 | sh = (mh - ih) * (1 - m->mfact); 30 | mh = (mh - ih) * m->mfact; 31 | sx = mx; 32 | sy = my + mh + ih; 33 | } 34 | #else 35 | sx = mx = m->wx; 36 | sy = my = m->wy; 37 | sh = mh = m->wh; 38 | sw = mw = m->ww; 39 | 40 | if (m->nmaster && n > m->nmaster) { 41 | sh = mh * (1 - m->mfact); 42 | mh = mh * m->mfact; 43 | sy = my + mh; 44 | } 45 | #endif // VANITYGAPS_PATCH 46 | 47 | getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest); 48 | 49 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { 50 | if (i < m->nmaster) { 51 | #if CFACTS_PATCH 52 | resize(c, mx, my, (mw / mfacts) * c->cfact + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); 53 | #else 54 | resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); 55 | #endif // CFACTS_PATCH 56 | #if VANITYGAPS_PATCH 57 | mx += WIDTH(c) + iv; 58 | #else 59 | mx += WIDTH(c); 60 | #endif 61 | } else { 62 | #if CFACTS_PATCH 63 | resize(c, sx, sy, (sw / sfacts) * c->cfact + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); 64 | #else 65 | resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); 66 | #endif // CFACTS_PATCH 67 | #if VANITYGAPS_PATCH 68 | sx += WIDTH(c) + iv; 69 | #else 70 | sx += WIDTH(c); 71 | #endif 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /patch/layout_columns.c: -------------------------------------------------------------------------------- 1 | static void 2 | col(Monitor *m) 3 | { 4 | unsigned int i, n; 5 | int mx = 0, my = 0, mh = 0, mw = 0; 6 | int sx = 0, sy = 0, sh = 0, sw = 0; 7 | float mfacts, sfacts; 8 | int mrest, srest; 9 | Client *c; 10 | 11 | #if VANITYGAPS_PATCH 12 | int oh, ov, ih, iv; 13 | getgaps(m, &oh, &ov, &ih, &iv, &n); 14 | #else 15 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 16 | #endif // VANITYGAPS_PATCH 17 | 18 | if (n == 0) 19 | return; 20 | 21 | #if VANITYGAPS_PATCH 22 | sx = mx = m->wx + ov; 23 | sy = my = m->wy + oh; 24 | mh = m->wh - 2*oh; 25 | sh = m->wh - 2*oh - ih * (n - m->nmaster - 1); 26 | mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1); 27 | sw = m->ww - 2*ov; 28 | 29 | if (m->nmaster && n > m->nmaster) { 30 | sw = (mw - iv) * (1 - m->mfact); 31 | mw = (mw - iv) * m->mfact; 32 | sx = mx + mw + iv * m->nmaster; 33 | } 34 | #else 35 | sx = mx = m->wx; 36 | sy = my = m->wy; 37 | sh = mh = m->wh; 38 | sw = mw = m->ww; 39 | 40 | if (m->nmaster && n > m->nmaster) { 41 | sw = mw * (1 - m->mfact); 42 | mw = mw * m->mfact; 43 | sx = mx + mw; 44 | } 45 | #endif // VANITYGAPS_PATCH 46 | 47 | getfacts(m, mw, sh, &mfacts, &sfacts, &mrest, &srest); 48 | 49 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 50 | if (i < m->nmaster) { 51 | #if CFACTS_PATCH 52 | resize(c, mx, my, (mw / mfacts) * c->cfact + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); 53 | #else 54 | resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); 55 | #endif // CFACTS_PATCH 56 | #if VANITYGAPS_PATCH 57 | mx += WIDTH(c) + iv; 58 | #else 59 | mx += WIDTH(c); 60 | #endif 61 | } else { 62 | #if CFACTS_PATCH 63 | resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) * c->cfact + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0); 64 | #else 65 | resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0); 66 | #endif // CFACTS_PATCH 67 | #if VANITYGAPS_PATCH 68 | sy += HEIGHT(c) + ih; 69 | #else 70 | sy += HEIGHT(c); 71 | #endif 72 | } 73 | } -------------------------------------------------------------------------------- /patch/focusadjacenttag.c: -------------------------------------------------------------------------------- 1 | void 2 | tagtoleft(const Arg *arg) 3 | { 4 | if (selmon->sel != NULL 5 | && __builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 6 | && selmon->tagset[selmon->seltags] > 1) { 7 | selmon->sel->tags >>= 1; 8 | focus(NULL); 9 | arrange(selmon); 10 | } 11 | } 12 | 13 | void 14 | tagtoright(const Arg *arg) 15 | { 16 | if (selmon->sel != NULL 17 | && __builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 18 | && selmon->tagset[selmon->seltags] & (TAGMASK >> 1)) { 19 | selmon->sel->tags <<= 1; 20 | focus(NULL); 21 | arrange(selmon); 22 | } 23 | } 24 | 25 | void 26 | viewtoleft(const Arg *arg) 27 | { 28 | if (__builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 29 | && selmon->tagset[selmon->seltags] > 1) { 30 | selmon->seltags ^= 1; /* toggle sel tagset */ 31 | selmon->tagset[selmon->seltags] = selmon->tagset[selmon->seltags ^ 1] >> 1; 32 | focus(NULL); 33 | arrange(selmon); 34 | } 35 | } 36 | 37 | void 38 | viewtoright(const Arg *arg) 39 | { 40 | if (__builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 41 | && selmon->tagset[selmon->seltags] & (TAGMASK >> 1)) { 42 | selmon->seltags ^= 1; /* toggle sel tagset */ 43 | selmon->tagset[selmon->seltags] = selmon->tagset[selmon->seltags ^ 1] << 1; 44 | focus(NULL); 45 | arrange(selmon); 46 | } 47 | } 48 | 49 | void 50 | tagandviewtoleft(const Arg *arg) 51 | { 52 | if (__builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 53 | && selmon->tagset[selmon->seltags] > 1) { 54 | selmon->sel->tags >>= 1; 55 | selmon->seltags ^= 1; /* toggle sel tagset */ 56 | selmon->tagset[selmon->seltags] = selmon->tagset[selmon->seltags ^ 1] >> 1; 57 | focus(selmon->sel); 58 | arrange(selmon); 59 | } 60 | } 61 | 62 | void 63 | tagandviewtoright(const Arg *arg) 64 | { 65 | if (__builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 66 | && selmon->tagset[selmon->seltags] & (TAGMASK >> 1)) { 67 | selmon->sel->tags <<= 1; 68 | selmon->seltags ^= 1; /* toggle sel tagset */ 69 | selmon->tagset[selmon->seltags] = selmon->tagset[selmon->seltags ^ 1] << 1; 70 | focus(selmon->sel); 71 | arrange(selmon); 72 | } 73 | } -------------------------------------------------------------------------------- /patch/layout_bstackhoriz.c: -------------------------------------------------------------------------------- 1 | static void 2 | bstackhoriz(Monitor *m) 3 | { 4 | unsigned int i, n; 5 | int mx = 0, my = 0, mh = 0, mw = 0; 6 | int sx = 0, sy = 0, sh = 0, sw = 0; 7 | float mfacts, sfacts; 8 | int mrest, srest; 9 | Client *c; 10 | 11 | #if VANITYGAPS_PATCH 12 | int oh, ov, ih, iv; 13 | getgaps(m, &oh, &ov, &ih, &iv, &n); 14 | #else 15 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 16 | #endif // VANITYGAPS_PATCH 17 | 18 | if (n == 0) 19 | return; 20 | 21 | #if VANITYGAPS_PATCH 22 | sx = mx = m->wx + ov; 23 | sy = my = m->wy + oh; 24 | mh = m->wh - 2*oh; 25 | sh = m->wh - 2*oh - ih * (n - m->nmaster - 1); 26 | mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1); 27 | sw = m->ww - 2*ov; 28 | 29 | if (m->nmaster && n > m->nmaster) { 30 | sh = (mh - ih) * (1 - m->mfact); 31 | mh = (mh - ih) * m->mfact; 32 | sy = my + mh + ih; 33 | sh = m->wh - mh - 2*oh - ih * (n - m->nmaster); 34 | } 35 | #else 36 | sx = mx = m->wx; 37 | sy = my = m->wy; 38 | sh = mh = m->wh; 39 | sw = mw = m->ww; 40 | 41 | if (m->nmaster && n > m->nmaster) { 42 | sh = mh * (1 - m->mfact); 43 | mh = mh * m->mfact; 44 | sy = my + mh; 45 | sh = m->wh - mh; 46 | } 47 | #endif // VANITYGAPS_PATCH 48 | 49 | getfacts(m, mw, sh, &mfacts, &sfacts, &mrest, &srest); 50 | 51 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { 52 | if (i < m->nmaster) { 53 | #if CFACTS_PATCH 54 | resize(c, mx, my, (mw / mfacts) * c->cfact + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); 55 | #else 56 | resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); 57 | #endif // CFACTS_PATCH 58 | #if VANITYGAPS_PATCH 59 | mx += WIDTH(c) + iv; 60 | #else 61 | mx += WIDTH(c); 62 | #endif 63 | } else { 64 | #if CFACTS_PATCH 65 | resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) * c->cfact + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0); 66 | #else 67 | resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0); 68 | #endif // CFACTS_PATCH 69 | #if VANITYGAPS_PATCH 70 | sy += HEIGHT(c) + ih; 71 | #else 72 | sy += HEIGHT(c); 73 | #endif 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /patch/autostart.c: -------------------------------------------------------------------------------- 1 | void 2 | runautostart(void) 3 | { 4 | char *pathpfx; 5 | char *path; 6 | char *xdgdatahome; 7 | char *home; 8 | 9 | if ((home = getenv("HOME")) == NULL) 10 | /* this is almost impossible */ 11 | return; 12 | 13 | /* if $XDG_DATA_HOME is defined, use $XDG_DATA_HOME/dwm, 14 | * otherwise use ~/.local/share/dwm as autostart script directory 15 | */ 16 | if ((xdgdatahome = getenv("XDG_DATA_HOME")) != NULL) { 17 | /* space for path segments, separators and nul */ 18 | if ((pathpfx = malloc(strlen(xdgdatahome) + strlen(dwmdir) + 2)) == NULL) 19 | return; 20 | 21 | if (sprintf(pathpfx, "%s/%s", xdgdatahome, dwmdir) <= 0) { 22 | free(pathpfx); 23 | return; 24 | } 25 | } else { 26 | /* space for path segments, separators and nul */ 27 | if ((pathpfx = malloc(strlen(home) + strlen(localshare) + strlen(dwmdir) + 3)) == NULL) 28 | return; 29 | 30 | if (sprintf(pathpfx, "%s/%s/%s", home, localshare, dwmdir) < 0) { 31 | free(pathpfx); 32 | return; 33 | } 34 | } 35 | 36 | /* check if the autostart script directory exists */ 37 | struct stat sb; 38 | 39 | if (! (stat(pathpfx, &sb) == 0 && S_ISDIR(sb.st_mode))) { 40 | /* the XDG conformant path does not exist or are not directories 41 | * so we try ~/.dwm instead 42 | */ 43 | if (realloc(pathpfx, strlen(home) + strlen(dwmdir) + 3) == NULL) { 44 | free(pathpfx); 45 | return; 46 | } 47 | 48 | if (sprintf(pathpfx, "%s/.%s", home, dwmdir) <= 0) { 49 | free(pathpfx); 50 | return; 51 | } 52 | } 53 | 54 | /* try the blocking script first */ 55 | if ((path = malloc(strlen(pathpfx) + strlen(autostartblocksh) + 2)) == NULL) { 56 | free(pathpfx); 57 | return; 58 | } else 59 | if (sprintf(path, "%s/%s", pathpfx, autostartblocksh) <= 0) { 60 | free(path); 61 | free(pathpfx); 62 | } 63 | 64 | if (access(path, X_OK) == 0) 65 | system(path); 66 | 67 | /* now the non-blocking script */ 68 | if ((path = realloc(path, strlen(pathpfx) + strlen(autostartsh) + 4)) == NULL) { 69 | free(pathpfx); 70 | free(path); 71 | return; 72 | } else 73 | if (sprintf(path, "%s/%s", pathpfx, autostartsh) <= 0) { 74 | free(path); 75 | free(pathpfx); 76 | } 77 | 78 | if (access(path, X_OK) == 0) { 79 | system(strcat(path, " &")); 80 | free(pathpfx); 81 | free(path); 82 | } 83 | } -------------------------------------------------------------------------------- /config.mk: -------------------------------------------------------------------------------- 1 | # ___ ______________ _ ____ ___ 2 | # | \/ | _ | _ | | | | \/ | 3 | # | . . | | | | | | | | | | . . | 4 | # | |\/| | | | | | | | |/\| | |\/| | 5 | # | | | \ \_/ | |/ /\ /\ | | | | 6 | # \_| |_/\___/|___/ \/ \/\_| |_/ 7 | # 8 | # MODWM - Modular Dynamic Window Manager. 9 | # --------------------------------------- 10 | # See LICENSE file for copyright and license details. 11 | 12 | # dwm version 13 | VERSION = 6.2 14 | 15 | # Customize below to fit your system 16 | 17 | # paths 18 | PREFIX = /usr/local 19 | MANPREFIX = ${PREFIX}/share/man 20 | 21 | X11INC = /usr/local/include 22 | X11LIB = /usr/local/lib 23 | 24 | # Xinerama, comment if you don't want it 25 | #XINERAMALIBS = -lXinerama 26 | #XINERAMAFLAGS = -DXINERAMA 27 | 28 | # freetype 29 | FREETYPELIBS = -lfontconfig -lXft 30 | FREETYPEINC = /usr/include/freetype2 31 | # OpenBSD (uncomment) 32 | FREETYPEINC = ${X11INC}/freetype2 33 | #KVMLIB = -lkvm 34 | 35 | # Uncomment this for the alpha patch / BAR_ALPHA_PATCH 36 | #XRENDER = -lXrender 37 | 38 | # Uncomment this for the mdpcontrol patch / MDPCONTROL_PATCH 39 | #MPDCLIENT = -lmpdclient 40 | 41 | # Uncomment for the pango patch / BAR_PANGO_PATCH 42 | #PANGOINC = `pkg-config --cflags xft pango pangoxft` 43 | #PANGOLIB = `pkg-config --libs xft pango pangoxft` 44 | 45 | # Uncomment for the ipc patch / IPC_PATCH 46 | #YAJLLIBS = -I-lyajl 47 | #YAJLINC = /usr/include/yajl 48 | 49 | # Uncomment this for the rounded corners patch / ROUNDED_CORNERS_PATCH 50 | #XEXTLIB = -lXext 51 | 52 | # Uncomment this for the swallow patch / SWALLOW_PATCH 53 | #XCBLIBS = -lX11-xcb -lxcb -lxcb-res ${KVMLIB} 54 | 55 | # includes and libs 56 | INCS = -I${X11INC} -I${FREETYPEINC} ${PANGOINC} ${YAJLLIBS} 57 | LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${XRENDER} ${MPDCLIENT} ${XEXTLIB} ${XCBLIBS} ${PANGOLIB} ${YAJLLIBS} 58 | 59 | # flags 60 | CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} 61 | #CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} 62 | CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} 63 | LDFLAGS = ${LIBS} 64 | 65 | # Solaris 66 | #CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" 67 | #LDFLAGS = ${LIBS} 68 | 69 | # compiler and linker 70 | CC = cc 71 | -------------------------------------------------------------------------------- /patch/bar_tags.c: -------------------------------------------------------------------------------- 1 | int 2 | width_tags(Bar *bar, BarArg *a) 3 | { 4 | int w, i; 5 | #if BAR_HIDEVACANTTAGS_PATCH 6 | Client *c; 7 | unsigned int occ = 0; 8 | for (c = bar->mon->clients; c; c = c->next) 9 | occ |= c->tags == 255 ? 0 : c->tags; 10 | #endif // BAR_HIDEVACANTTAGS_PATCH 11 | 12 | for (w = 0, i = 0; i < NUMTAGS; i++) { 13 | #if BAR_HIDEVACANTTAGS_PATCH 14 | if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i)) 15 | continue; 16 | #endif // BAR_HIDEVACANTTAGS_PATCH 17 | w += TEXTW(tagicon(bar->mon, i)); 18 | } 19 | return w; 20 | } 21 | 22 | int 23 | draw_tags(Bar *bar, BarArg *a) 24 | { 25 | int invert; 26 | int w, x = a->x; 27 | unsigned int i, occ = 0, urg = 0; 28 | char *icon; 29 | Client *c; 30 | Monitor *m = bar->mon; 31 | 32 | for (c = m->clients; c; c = c->next) { 33 | #if BAR_HIDEVACANTTAGS_PATCH 34 | occ |= c->tags == 255 ? 0 : c->tags; 35 | #else 36 | occ |= c->tags; 37 | #endif // BAR_HIDEVACANTTAGS_PATCH 38 | if (c->isurgent) 39 | urg |= c->tags; 40 | } 41 | for (i = 0; i < NUMTAGS; i++) { 42 | #if BAR_HIDEVACANTTAGS_PATCH 43 | /* do not draw vacant tags */ 44 | if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) 45 | continue; 46 | #endif // BAR_HIDEVACANTTAGS_PATCH 47 | 48 | icon = tagicon(bar->mon, i); 49 | invert = 0; 50 | w = TEXTW(icon); 51 | drw_setscheme(drw, scheme[ 52 | m->tagset[m->seltags] & 1 << i 53 | ? SchemeTagsSel 54 | : urg & 1 << i 55 | ? SchemeUrg 56 | : SchemeTagsNorm 57 | ]); 58 | drw_text(drw, x, a->y, w, a->h, lrpad / 2, icon, invert, False); 59 | drawindicator(m, NULL, occ, x, a->y, w, a->h, i, -1, invert, tagindicatortype); 60 | x += w; 61 | } 62 | 63 | return 1; 64 | } 65 | 66 | int 67 | click_tags(Bar *bar, Arg *arg, BarArg *a) 68 | { 69 | int i = 0, x = lrpad / 2; 70 | #if BAR_HIDEVACANTTAGS_PATCH 71 | Client *c; 72 | unsigned int occ = 0; 73 | for (c = bar->mon->clients; c; c = c->next) 74 | occ |= c->tags == 255 ? 0 : c->tags; 75 | #endif // BAR_HIDEVACANTTAGS_PATCH 76 | 77 | do { 78 | #if BAR_HIDEVACANTTAGS_PATCH 79 | if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i)) 80 | continue; 81 | #endif // BAR_HIDEVACANTTAGS_PATCH 82 | x += TEXTW(tagicon(bar->mon, i)); 83 | } while (a->x >= x && ++i < NUMTAGS); 84 | if (i < NUMTAGS) { 85 | arg->ui = 1 << i; 86 | } 87 | return ClkTagBar; 88 | } 89 | -------------------------------------------------------------------------------- /patch/dwmc.c: -------------------------------------------------------------------------------- 1 | void 2 | setlayoutex(const Arg *arg) 3 | { 4 | setlayout(&((Arg) { .v = &layouts[arg->i] })); 5 | } 6 | 7 | void 8 | viewex(const Arg *arg) 9 | { 10 | view(&((Arg) { .ui = 1 << arg->ui })); 11 | } 12 | 13 | void 14 | viewallex(const Arg *arg) 15 | { 16 | view(&((Arg){.ui = ~0})); 17 | } 18 | 19 | void 20 | toggleviewex(const Arg *arg) 21 | { 22 | toggleview(&((Arg) { .ui = 1 << arg->ui })); 23 | } 24 | 25 | void 26 | tagex(const Arg *arg) 27 | { 28 | tag(&((Arg) { .ui = 1 << arg->ui })); 29 | } 30 | 31 | void 32 | toggletagex(const Arg *arg) 33 | { 34 | toggletag(&((Arg) { .ui = 1 << arg->ui })); 35 | } 36 | 37 | void 38 | tagallex(const Arg *arg) 39 | { 40 | tag(&((Arg){.ui = ~0})); 41 | } 42 | 43 | int 44 | fake_signal(void) 45 | { 46 | char fsignal[256]; 47 | char indicator[9] = "fsignal:"; 48 | char str_sig[50]; 49 | char param[16]; 50 | int i, len_str_sig, n, paramn; 51 | size_t len_fsignal, len_indicator = strlen(indicator); 52 | Arg arg; 53 | 54 | // Get root name property 55 | if (gettextprop(root, XA_WM_NAME, fsignal, sizeof(fsignal))) { 56 | len_fsignal = strlen(fsignal); 57 | 58 | // Check if this is indeed a fake signal 59 | if (len_indicator > len_fsignal ? 0 : strncmp(indicator, fsignal, len_indicator) == 0) { 60 | paramn = sscanf(fsignal+len_indicator, "%s%n%s%n", str_sig, &len_str_sig, param, &n); 61 | 62 | if (paramn == 1) arg = (Arg) {0}; 63 | else if (paramn > 2) return 1; 64 | else if (strncmp(param, "i", n - len_str_sig) == 0) 65 | #if IPC_PATCH 66 | sscanf(fsignal + len_indicator + n, "%li", &(arg.i)); 67 | #else 68 | sscanf(fsignal + len_indicator + n, "%i", &(arg.i)); 69 | #endif // IPC_PATCH 70 | else if (strncmp(param, "ui", n - len_str_sig) == 0) 71 | #if IPC_PATCH 72 | sscanf(fsignal + len_indicator + n, "%lu", &(arg.ui)); 73 | #else 74 | sscanf(fsignal + len_indicator + n, "%u", &(arg.ui)); 75 | #endif // IPC_PATCH 76 | else if (strncmp(param, "f", n - len_str_sig) == 0) 77 | sscanf(fsignal + len_indicator + n, "%f", &(arg.f)); 78 | else return 1; 79 | 80 | // Check if a signal was found, and if so handle it 81 | for (i = 0; i < LENGTH(signals); i++) 82 | if (strncmp(str_sig, signals[i].sig, len_str_sig) == 0 && signals[i].func) 83 | signals[i].func(&(arg)); 84 | 85 | // A fake signal was sent 86 | return 1; 87 | } 88 | } 89 | 90 | // No fake signal was sent, so proceed with update 91 | return 0; 92 | } 93 | -------------------------------------------------------------------------------- /patch/layout_gapplessgrid.c: -------------------------------------------------------------------------------- 1 | #if VANITYGAPS_PATCH 2 | void 3 | gaplessgrid(Monitor *m) 4 | { 5 | unsigned int i, n; 6 | int x, y, cols, rows, ch, cw, cn, rn, rrest, crest; // counters 7 | int oh, ov, ih, iv; 8 | Client *c; 9 | 10 | getgaps(m, &oh, &ov, &ih, &iv, &n); 11 | if (n == 0) 12 | return; 13 | 14 | /* grid dimensions */ 15 | for (cols = 0; cols <= n/2; cols++) 16 | if (cols*cols >= n) 17 | break; 18 | if (n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */ 19 | cols = 2; 20 | rows = n/cols; 21 | cn = rn = 0; // reset column no, row no, client count 22 | 23 | ch = (m->wh - 2*oh - ih * (rows - 1)) / rows; 24 | cw = (m->ww - 2*ov - iv * (cols - 1)) / cols; 25 | rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows; 26 | crest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols; 27 | x = m->wx + ov; 28 | y = m->wy + oh; 29 | 30 | for (i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) { 31 | if (i/rows + 1 > cols - n%cols) { 32 | rows = n/cols + 1; 33 | ch = (m->wh - 2*oh - ih * (rows - 1)) / rows; 34 | rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows; 35 | } 36 | resize(c, 37 | x, 38 | y + rn*(ch + ih) + MIN(rn, rrest), 39 | cw + (cn < crest ? 1 : 0) - 2*c->bw, 40 | ch + (rn < rrest ? 1 : 0) - 2*c->bw, 41 | 0); 42 | rn++; 43 | if (rn >= rows) { 44 | rn = 0; 45 | x += cw + ih + (cn < crest ? 1 : 0); 46 | cn++; 47 | } 48 | } 49 | } 50 | #else 51 | void 52 | gaplessgrid(Monitor *m) 53 | { 54 | unsigned int i, n; 55 | int x, y, cols, rows, ch, cw, cn, rn, rrest, crest; // counters 56 | Client *c; 57 | 58 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 59 | if (n == 0) 60 | return; 61 | 62 | /* grid dimensions */ 63 | for (cols = 0; cols <= n/2; cols++) 64 | if (cols*cols >= n) 65 | break; 66 | if (n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */ 67 | cols = 2; 68 | rows = n/cols; 69 | cn = rn = 0; // reset column no, row no, client count 70 | 71 | ch = m->wh / rows; 72 | cw = m->ww / cols; 73 | rrest = m->wh - ch * rows; 74 | crest = m->ww - cw * cols; 75 | x = m->wx; 76 | y = m->wy; 77 | 78 | for (i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) { 79 | if (i/rows + 1 > cols - n%cols) { 80 | rows = n/cols + 1; 81 | ch = m->wh / rows; 82 | rrest = m->wh - ch * rows; 83 | } 84 | resize(c, 85 | x, 86 | y + rn*ch + MIN(rn, rrest), 87 | cw + (cn < crest ? 1 : 0) - 2*c->bw, 88 | ch + (rn < rrest ? 1 : 0) - 2*c->bw, 89 | 0); 90 | rn++; 91 | if (rn >= rows) { 92 | rn = 0; 93 | x += cw + (cn < crest ? 1 : 0); 94 | cn++; 95 | } 96 | } 97 | } 98 | #endif 99 | -------------------------------------------------------------------------------- /patch/layout_nrowgrid.c: -------------------------------------------------------------------------------- 1 | #if VANITYGAPS_PATCH 2 | void 3 | nrowgrid(Monitor *m) 4 | { 5 | unsigned int n = 0, i = 0, ri = 0, ci = 0; /* counters */ 6 | int oh, ov, ih, iv; /* vanitygap settings */ 7 | unsigned int cx, cy, cw, ch; /* client geometry */ 8 | unsigned int uw = 0, uh = 0, uc = 0; /* utilization trackers */ 9 | unsigned int cols, rows = m->nmaster + 1; 10 | Client *c; 11 | 12 | /* count clients */ 13 | getgaps(m, &oh, &ov, &ih, &iv, &n); 14 | 15 | /* nothing to do here */ 16 | if (n == 0) 17 | return; 18 | 19 | /* force 2 clients to always split vertically */ 20 | if (FORCE_VSPLIT && n == 2) 21 | rows = 1; 22 | 23 | /* never allow empty rows */ 24 | if (n < rows) 25 | rows = n; 26 | 27 | /* define first row */ 28 | cols = n / rows; 29 | uc = cols; 30 | cy = m->wy + oh; 31 | ch = (m->wh - 2*oh - ih*(rows - 1)) / rows; 32 | uh = ch; 33 | 34 | for (c = nexttiled(m->clients); c; c = nexttiled(c->next), i++, ci++) { 35 | if (ci == cols) { 36 | uw = 0; 37 | ci = 0; 38 | ri++; 39 | 40 | /* next row */ 41 | cols = (n - uc) / (rows - ri); 42 | uc += cols; 43 | cy = m->wy + oh + uh + ih; 44 | uh += ch + ih; 45 | } 46 | 47 | cx = m->wx + ov + uw; 48 | cw = (m->ww - 2*ov - uw) / (cols - ci); 49 | uw += cw + iv; 50 | 51 | resize(c, cx, cy, cw - (2*c->bw), ch - (2*c->bw), 0); 52 | } 53 | } 54 | #else 55 | void 56 | nrowgrid(Monitor *m) 57 | { 58 | unsigned int n = 0, i = 0, ri = 0, ci = 0; /* counters */ 59 | unsigned int cx, cy, cw, ch; /* client geometry */ 60 | unsigned int uw = 0, uh = 0, uc = 0; /* utilization trackers */ 61 | unsigned int cols, rows = m->nmaster + 1; 62 | Client *c; 63 | 64 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 65 | if (n == 0) 66 | return; 67 | 68 | /* force 2 clients to always split vertically */ 69 | if (FORCE_VSPLIT && n == 2) 70 | rows = 1; 71 | 72 | /* never allow empty rows */ 73 | if (n < rows) 74 | rows = n; 75 | 76 | /* define first row */ 77 | cols = n / rows; 78 | uc = cols; 79 | cy = m->wy; 80 | ch = m->wh / rows; 81 | uh = ch; 82 | 83 | for (c = nexttiled(m->clients); c; c = nexttiled(c->next), i++, ci++) { 84 | if (ci == cols) { 85 | uw = 0; 86 | ci = 0; 87 | ri++; 88 | 89 | /* next row */ 90 | cols = (n - uc) / (rows - ri); 91 | uc += cols; 92 | cy = m->wy + uh; 93 | uh += ch; 94 | } 95 | 96 | cx = m->wx + uw; 97 | cw = (m->ww - uw) / (cols - ci); 98 | uw += cw; 99 | 100 | resize(c, cx, cy, cw - (2*c->bw), ch - (2*c->bw), 0); 101 | } 102 | } 103 | #endif -------------------------------------------------------------------------------- /patch/dwmc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | signal() { 4 | xsetroot -name "fsignal:$*" 5 | } 6 | 7 | case $# in 8 | 1) 9 | case $1 in 10 | focusurgent) ;& 11 | mirrorlayout) ;& 12 | mpdcontrol) ;& 13 | pushdown) ;& 14 | pushup) ;& 15 | self_restart) ;& 16 | setlayout) ;& 17 | setcfact) ;& 18 | switchcol) ;& 19 | view) ;& 20 | viewall) ;& 21 | viewtoleft) ;& 22 | viewtoright) ;& 23 | tagtoleft) ;& 24 | tagtoright) ;& 25 | tagandviewtoleft) ;& 26 | tagandviewtoright) ;& 27 | transfer) ;& 28 | transferall) ;& 29 | togglealttag) ;& 30 | togglebar) ;& 31 | togglefloating) ;& 32 | togglefullscreen) ;& 33 | fullscreen) ;& 34 | togglefakefullscreen) ;& 35 | togglesticky) ;& 36 | togglehorizontalmax) ;& 37 | toggleverticalmax) ;& 38 | togglemax) ;& 39 | togglegaps) ;& 40 | defaultgaps) ;& 41 | unfloatvisible) ;& 42 | winview) ;& 43 | xrdb) ;& 44 | zoom) ;& 45 | killclient) ;& 46 | quit) 47 | signal $1 48 | ;; 49 | *) 50 | echo "Unknown command ($1) or missing one argument." 51 | exit 1 52 | ;; 53 | esac 54 | ;; 55 | 2) 56 | case $1 in 57 | cyclelayout) ;& 58 | explace) ;& 59 | moveplace) ;& 60 | mpdchange) ;& 61 | setkeymode) ;& 62 | switchtag) ;& 63 | togglescratch) ;& 64 | view) 65 | signal $1 ui $2 66 | ;; 67 | viewex) ;& 68 | toggleviewex) ;& 69 | tagallmon) ;& 70 | tagswapmon) ;& 71 | tagex) ;& 72 | toggletagex) ;& 73 | setborderpx) ;& 74 | setgaps) ;& 75 | setlayoutex) ;& 76 | setlayoutaxisex) ;& 77 | swapfocus) ;& 78 | focusstack) ;& 79 | pushstack) ;& 80 | inplacerotate) ;& 81 | rotatestack) ;& 82 | rotatelayoutaxis) ;& 83 | incnmaster) ;& 84 | incnstack) ;& 85 | incrgaps) ;& 86 | incrigaps) ;& 87 | incrogaps) ;& 88 | incrihgaps) ;& 89 | incrivgaps) ;& 90 | incrohgaps) ;& 91 | incrovgaps) ;& 92 | movestack) ;& 93 | shiftview) ;& 94 | shiftviewclients) ;& 95 | focusmon) ;& 96 | tagmon) 97 | signal $1 i $2 98 | ;; 99 | setcfact) ;& 100 | setmfact) 101 | signal $1 f $2 102 | ;; 103 | *) 104 | echo "Unknown command ($1) or too many arguments" 105 | exit 1 106 | ;; 107 | esac 108 | ;; 109 | 5) 110 | case $1 in 111 | setgaps) 112 | # Expects "setgaps oh ov ih iv" where -1 means to keep existing values 113 | [ $2 = -1 ] && oh=128 || oh=$2 114 | [ $3 = -1 ] && ov=128 || ov=$3 115 | [ $4 = -1 ] && ih=128 || ih=$4 116 | [ $5 = -1 ] && iv=128 || iv=$5 117 | signal $1 i $(((oh << 24) + (ov << 16) + (ih << 8) + iv)) 118 | ;; 119 | *) 120 | echo "Unknown command ($1) or too many arguments" 121 | exit 1 122 | ;; 123 | esac 124 | ;; 125 | *) 126 | echo "Unknown command ($1) or too many arguments" 127 | exit 1 128 | ;; 129 | esac 130 | -------------------------------------------------------------------------------- /patch/pertag.c: -------------------------------------------------------------------------------- 1 | struct Pertag { 2 | unsigned int curtag, prevtag; /* current and previous tag */ 3 | int nmasters[NUMTAGS + 1]; /* number of windows in master area */ 4 | #if FLEXTILE_DELUXE_LAYOUT 5 | int nstacks[NUMTAGS + 1]; /* number of windows in primary stack area */ 6 | int ltaxis[NUMTAGS + 1][LTAXIS_LAST]; 7 | const Layout *ltidxs[NUMTAGS + 1][3]; /* matrix of tags and layouts indexes */ 8 | #else 9 | const Layout *ltidxs[NUMTAGS + 1][2]; /* matrix of tags and layouts indexes */ 10 | #endif // FLEXTILE_DELUXE_LAYOUT 11 | float mfacts[NUMTAGS + 1]; /* mfacts per tag */ 12 | unsigned int sellts[NUMTAGS + 1]; /* selected layouts */ 13 | #if PERTAGBAR_PATCH 14 | int showbars[NUMTAGS + 1]; /* display bar for the current tag */ 15 | #endif // PERTAGBAR_PATCH 16 | #if SWAPFOCUS_PATCH 17 | Client *prevclient[NUMTAGS + 1]; 18 | #endif // SWAPFOCUS_PATCH 19 | #if ZOOMSWAP_PATCH 20 | Client *prevzooms[NUMTAGS + 1]; /* store zoom information */ 21 | #endif // ZOOMSWAP_PATCH 22 | #if VANITYGAPS_PATCH 23 | int enablegaps[NUMTAGS + 1]; 24 | #endif // VANITYGAPS_PATCH 25 | }; 26 | 27 | void 28 | pertagview(const Arg *arg) 29 | { 30 | int i; 31 | unsigned int tmptag; 32 | if (arg->ui & TAGMASK) { 33 | selmon->pertag->prevtag = selmon->pertag->curtag; 34 | selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; 35 | if (arg->ui == ~0) 36 | selmon->pertag->curtag = 0; 37 | else { 38 | for (i = 0; !(arg->ui & 1 << i); i++) ; 39 | selmon->pertag->curtag = i + 1; 40 | } 41 | } else { 42 | tmptag = selmon->pertag->prevtag; 43 | selmon->pertag->prevtag = selmon->pertag->curtag; 44 | selmon->pertag->curtag = tmptag; 45 | } 46 | selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; 47 | #if FLEXTILE_DELUXE_LAYOUT 48 | selmon->nstack = selmon->pertag->nstacks[selmon->pertag->curtag]; 49 | #endif // FLEXTILE_DELUXE_LAYOUT 50 | selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; 51 | selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; 52 | selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; 53 | selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; 54 | 55 | #if FLEXTILE_DELUXE_LAYOUT 56 | selmon->ltaxis[LAYOUT] = selmon->pertag->ltaxis[selmon->pertag->curtag][LAYOUT]; 57 | selmon->ltaxis[MASTER] = selmon->pertag->ltaxis[selmon->pertag->curtag][MASTER]; 58 | selmon->ltaxis[STACK] = selmon->pertag->ltaxis[selmon->pertag->curtag][STACK]; 59 | selmon->ltaxis[STACK2] = selmon->pertag->ltaxis[selmon->pertag->curtag][STACK2]; 60 | #endif // FLEXTILE_DELUXE_LAYOUT 61 | #if PERTAGBAR_PATCH 62 | if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) 63 | togglebar(NULL); 64 | #endif // PERTAGBAR_PATCH 65 | } -------------------------------------------------------------------------------- /patch/ipc.c: -------------------------------------------------------------------------------- 1 | static int epoll_fd; 2 | static int dpy_fd; 3 | static Monitor *lastselmon; 4 | 5 | int 6 | handlexevent(struct epoll_event *ev) 7 | { 8 | if (ev->events & EPOLLIN) { 9 | XEvent ev; 10 | while (running && XPending(dpy)) { 11 | XNextEvent(dpy, &ev); 12 | if (handler[ev.type]) { 13 | handler[ev.type](&ev); /* call handler */ 14 | ipc_send_events(mons, &lastselmon, selmon); 15 | } 16 | } 17 | } else if (ev-> events & EPOLLHUP) 18 | return -1; 19 | 20 | return 0; 21 | } 22 | 23 | void 24 | setlayoutsafe(const Arg *arg) 25 | { 26 | const Layout *ltptr = (Layout *)arg->v; 27 | if (ltptr == 0) 28 | setlayout(arg); 29 | for (int i = 0; i < LENGTH(layouts); i++) { 30 | if (ltptr == &layouts[i]) 31 | setlayout(arg); 32 | } 33 | } 34 | 35 | void 36 | setupepoll(void) 37 | { 38 | epoll_fd = epoll_create1(0); 39 | dpy_fd = ConnectionNumber(dpy); 40 | struct epoll_event dpy_event; 41 | 42 | // Initialize struct to 0 43 | memset(&dpy_event, 0, sizeof(dpy_event)); 44 | 45 | DEBUG("Display socket is fd %d\n", dpy_fd); 46 | 47 | if (epoll_fd == -1) 48 | fputs("Failed to create epoll file descriptor", stderr); 49 | 50 | dpy_event.events = EPOLLIN; 51 | dpy_event.data.fd = dpy_fd; 52 | if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, dpy_fd, &dpy_event)) { 53 | fputs("Failed to add display file descriptor to epoll", stderr); 54 | close(epoll_fd); 55 | exit(1); 56 | } 57 | 58 | if (ipc_init(ipcsockpath, epoll_fd, ipccommands, LENGTH(ipccommands)) < 0) 59 | fputs("Failed to initialize IPC\n", stderr); 60 | } 61 | 62 | void 63 | setstatus(const Arg *arg) 64 | { 65 | Monitor *m; 66 | #if BAR_EXTRASTATUS_PATCH 67 | if (arg->v == NULL) { 68 | strcpy(stext, "dwm-"VERSION); 69 | estext[0] = '\0'; 70 | } else { 71 | strcpy(rawstext, arg->v); 72 | char *e = strchr(rawstext, statussep); 73 | if (e) { 74 | *e = '\0'; e++; 75 | #if BAR_STATUSCMD_PATCH 76 | strncpy(rawestext, e, sizeof(estext) - 1); 77 | copyvalidchars(estext, rawestext); 78 | #else 79 | strncpy(estext, e, sizeof(estext) - 1); 80 | #endif // BAR_STATUSCMD_PATCH 81 | } else { 82 | estext[0] = '\0'; 83 | } 84 | #if BAR_STATUSCMD_PATCH 85 | copyvalidchars(stext, rawstext); 86 | #else 87 | strncpy(stext, rawstext, sizeof(stext) - 1); 88 | #endif // BAR_STATUSCMD_PATCH 89 | } 90 | #elif BAR_STATUSCMD_PATCH 91 | if (!gettextprop(root, XA_WM_NAME, rawstext, sizeof(rawstext))) 92 | strcpy(stext, "dwm-"VERSION); 93 | else 94 | copyvalidchars(stext, rawstext); 95 | #else 96 | if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) 97 | strcpy(stext, "dwm-"VERSION); 98 | #endif // BAR_EXTRASTATUS_PATCH | BAR_STATUSCMD_PATCH 99 | for (m = mons; m; m = m->next) 100 | drawbar(m); 101 | } -------------------------------------------------------------------------------- /patch/layout_centeredfloatingmaster.c: -------------------------------------------------------------------------------- 1 | void 2 | centeredfloatingmaster(Monitor *m) 3 | { 4 | unsigned int i, n; 5 | float mfacts, sfacts; 6 | int mrest, srest; 7 | int mx = 0, my = 0, mh = 0, mw = 0; 8 | int sx = 0, sy = 0, sh = 0, sw = 0; 9 | Client *c; 10 | 11 | #if VANITYGAPS_PATCH 12 | float mivf = 1.0; // master inner vertical gap factor 13 | int oh, ov, ih, iv; 14 | getgaps(m, &oh, &ov, &ih, &iv, &n); 15 | #else 16 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 17 | #endif // VANITYGAPS_PATCH 18 | 19 | if (n == 0) 20 | return; 21 | 22 | #if VANITYGAPS_PATCH 23 | sx = mx = m->wx + ov; 24 | sy = my = m->wy + oh; 25 | sh = mh = m->wh - 2*oh; 26 | mw = m->ww - 2*ov - iv*(n - 1); 27 | sw = m->ww - 2*ov - iv*(n - m->nmaster - 1); 28 | 29 | if (m->nmaster && n > m->nmaster) { 30 | mivf = 0.8; 31 | /* go mfact box in the center if more than nmaster clients */ 32 | if (m->ww > m->wh) { 33 | mw = m->ww * m->mfact - iv*mivf*(MIN(n, m->nmaster) - 1); 34 | mh = m->wh * 0.9; 35 | } else { 36 | mw = m->ww * 0.9 - iv*mivf*(MIN(n, m->nmaster) - 1); 37 | mh = m->wh * m->mfact; 38 | } 39 | mx = m->wx + (m->ww - mw) / 2; 40 | my = m->wy + (m->wh - mh - 2*oh) / 2; 41 | 42 | sx = m->wx + ov; 43 | sy = m->wy + oh; 44 | sh = m->wh - 2*oh; 45 | } 46 | #else 47 | sx = mx = m->wx; 48 | sy = my = m->wy; 49 | sh = mh = m->wh; 50 | sw = mw = m->ww; 51 | 52 | if (m->nmaster && n > m->nmaster) { 53 | /* go mfact box in the center if more than nmaster clients */ 54 | if (m->ww > m->wh) { 55 | mw = m->ww * m->mfact; 56 | mh = m->wh * 0.9; 57 | } else { 58 | mw = m->ww * 0.9; 59 | mh = m->wh * m->mfact; 60 | } 61 | mx = m->wx + (m->ww - mw) / 2; 62 | my = m->wy + (m->wh - mh) / 2; 63 | } 64 | #endif // VANITYGAPS_PATCH 65 | 66 | getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest); 67 | 68 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 69 | if (i < m->nmaster) { 70 | /* nmaster clients are stacked horizontally, in the center of the screen */ 71 | #if CFACTS_PATCH 72 | resize(c, mx, my, (mw / mfacts) * c->cfact + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); 73 | #else 74 | resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); 75 | #endif // CFACTS_PATCH 76 | #if VANITYGAPS_PATCH 77 | mx += WIDTH(c) + iv*mivf; 78 | #else 79 | mx += WIDTH(c); 80 | #endif 81 | } else { 82 | /* stack clients are stacked horizontally */ 83 | #if CFACTS_PATCH 84 | resize(c, sx, sy, (sw / sfacts) * c->cfact + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); 85 | #else 86 | resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); 87 | #endif // CFACTS_PATCH 88 | #if VANITYGAPS_PATCH 89 | sx += WIDTH(c) + iv; 90 | #else 91 | sx += WIDTH(c); 92 | #endif 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /patch/layout_horizgrid.c: -------------------------------------------------------------------------------- 1 | void 2 | horizgrid(Monitor *m) { 3 | Client *c; 4 | unsigned int n, i; 5 | int mx = 0, my = 0, mh = 0, mw = 0; 6 | int sx = 0, sy = 0, sh = 0, sw = 0; 7 | int ntop; 8 | float mfacts = 0, sfacts = 0; 9 | int mrest, srest, mtotal = 0, stotal = 0; 10 | 11 | #if VANITYGAPS_PATCH 12 | int oh, ov, ih, iv; 13 | getgaps(m, &oh, &ov, &ih, &iv, &n); 14 | #else 15 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 16 | #endif // VANITYGAPS_PATCH 17 | if (n == 0) 18 | return; 19 | 20 | if (n <= 2) 21 | ntop = n; 22 | else { 23 | ntop = n / 2; 24 | } 25 | 26 | #if VANITYGAPS_PATCH 27 | sx = mx = m->wx + ov; 28 | sy = my = m->wy + oh; 29 | sh = mh = m->wh - 2*oh; 30 | sw = mw = m->ww - 2*ov; 31 | 32 | if (n > ntop) { 33 | sh = (mh - ih) / 2; 34 | mh = mh - ih - sh; 35 | sy = my + mh + ih; 36 | mw = m->ww - 2*ov - iv * (ntop - 1); 37 | sw = m->ww - 2*ov - iv * (n - ntop - 1); 38 | } 39 | #else 40 | sx = mx = m->wx; 41 | sy = my = m->wy; 42 | sh = mh = m->wh; 43 | sw = mw = m->ww; 44 | 45 | if (n > ntop) { 46 | sh = mh / 2; 47 | mh = mh - sh; 48 | sy = my + mh; 49 | } 50 | #endif // VANITYGAPS_PATCH 51 | 52 | /* calculate facts */ 53 | #if CFACTS_PATCH 54 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 55 | if (i < ntop) 56 | mfacts += c->cfact; 57 | else 58 | sfacts += c->cfact; 59 | 60 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 61 | if (i < ntop) 62 | mtotal += mh * (c->cfact / mfacts); 63 | else 64 | stotal += sw * (c->cfact / sfacts); 65 | #else 66 | mfacts = ntop; 67 | sfacts = n - ntop; 68 | 69 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 70 | if (i < ntop) 71 | mtotal += mh / mfacts; 72 | else 73 | stotal += sw / sfacts; 74 | #endif // CFACTS_PATCH 75 | 76 | mrest = mh - mtotal; 77 | srest = sw - stotal; 78 | 79 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) 80 | if (i < ntop) { 81 | #if CFACTS_PATCH 82 | resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); 83 | #else 84 | resize(c, mx, my, mw / mfacts + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); 85 | #endif // CFACTS_PATCH 86 | #if VANITYGAPS_PATCH 87 | mx += WIDTH(c) + iv; 88 | #else 89 | mx += WIDTH(c); 90 | #endif // VANITYGAPS_PATCH 91 | } else { 92 | #if CFACTS_PATCH 93 | resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - ntop) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); 94 | #else 95 | resize(c, sx, sy, sw / sfacts + ((i - ntop) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); 96 | #endif // CFACTS_PATCH 97 | #if VANITYGAPS_PATCH 98 | sx += WIDTH(c) + iv; 99 | #else 100 | sx += WIDTH(c); 101 | #endif // VANITYGAPS_PATCH 102 | } 103 | } -------------------------------------------------------------------------------- /patch/ipc/yajl_dumps.h: -------------------------------------------------------------------------------- 1 | #ifndef YAJL_DUMPS_H_ 2 | #define YAJL_DUMPS_H_ 3 | 4 | #include 5 | #include 6 | 7 | #define YSTR(str) yajl_gen_string(gen, (unsigned char *)str, strlen(str)) 8 | #define YINT(num) yajl_gen_integer(gen, num) 9 | #define YDOUBLE(num) yajl_gen_double(gen, num) 10 | #define YBOOL(v) yajl_gen_bool(gen, v) 11 | #define YNULL() yajl_gen_null(gen) 12 | #define YARR(body) \ 13 | { \ 14 | yajl_gen_array_open(gen); \ 15 | body; \ 16 | yajl_gen_array_close(gen); \ 17 | } 18 | #define YMAP(body) \ 19 | { \ 20 | yajl_gen_map_open(gen); \ 21 | body; \ 22 | yajl_gen_map_close(gen); \ 23 | } 24 | 25 | int dump_tag(yajl_gen gen, const char *name, const int tag_mask); 26 | 27 | int dump_tags(yajl_gen gen, int tags_len); 28 | 29 | int dump_client(yajl_gen gen, Client *c); 30 | 31 | int dump_monitor(yajl_gen gen, Monitor *mon, int is_selected); 32 | 33 | int dump_monitors(yajl_gen gen, Monitor *mons, Monitor *selmon); 34 | 35 | int dump_layouts(yajl_gen gen, const Layout layouts[], const int layouts_len); 36 | 37 | int dump_tag_state(yajl_gen gen, TagState state); 38 | 39 | int dump_tag_event(yajl_gen gen, int mon_num, TagState old_state, 40 | TagState new_state); 41 | 42 | int dump_client_focus_change_event(yajl_gen gen, Client *old_client, 43 | Client *new_client, int mon_num); 44 | 45 | int dump_layout_change_event(yajl_gen gen, const int mon_num, 46 | const char *old_symbol, const Layout *old_layout, 47 | const char *new_symbol, const Layout *new_layout); 48 | 49 | int dump_monitor_focus_change_event(yajl_gen gen, const int last_mon_num, 50 | const int new_mon_num); 51 | 52 | int dump_focused_title_change_event(yajl_gen gen, const int mon_num, 53 | const Window client_id, 54 | const char *old_name, const char *new_name); 55 | 56 | int dump_client_state(yajl_gen gen, const ClientState *state); 57 | 58 | int dump_focused_state_change_event(yajl_gen gen, const int mon_num, 59 | const Window client_id, 60 | const ClientState *old_state, 61 | const ClientState *new_state); 62 | 63 | int dump_error_message(yajl_gen gen, const char *reason); 64 | 65 | #endif // YAJL_DUMPS_H_ 66 | -------------------------------------------------------------------------------- /patch/bar_powerline_tags.c: -------------------------------------------------------------------------------- 1 | int 2 | width_pwrl_tags(Bar *bar, BarArg *a) 3 | { 4 | int w, i; 5 | int plw = drw->fonts->h / 2 + 1; 6 | #if BAR_HIDEVACANTTAGS_PATCH 7 | Client *c; 8 | unsigned int occ = 0; 9 | for (c = bar->mon->clients; c; c = c->next) 10 | occ |= c->tags == 255 ? 0 : c->tags; 11 | #endif // BAR_HIDEVACANTTAGS_PATCH 12 | 13 | for (w = 0, i = 0; i < NUMTAGS; i++) { 14 | #if BAR_HIDEVACANTTAGS_PATCH 15 | if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i)) 16 | continue; 17 | #endif // BAR_HIDEVACANTTAGS_PATCH 18 | w += TEXTW(tagicon(bar->mon, i)) + plw; 19 | } 20 | return w + lrpad; 21 | } 22 | 23 | int 24 | draw_pwrl_tags(Bar *bar, BarArg *a) 25 | { 26 | int x, w; 27 | int invert; 28 | int plw = drw->fonts->h / 2 + 1; 29 | unsigned int i, occ = 0, urg = 0; 30 | char *icon; 31 | Client *c; 32 | Clr *prevscheme, *nxtscheme; 33 | 34 | for (c = bar->mon->clients; c; c = c->next) { 35 | #if BAR_HIDEVACANTTAGS_PATCH 36 | occ |= c->tags == 255 ? 0 : c->tags; 37 | #else 38 | occ |= c->tags; 39 | #endif // BAR_HIDEVACANTTAGS_PATCH 40 | if (c->isurgent) 41 | urg |= c->tags; 42 | } 43 | x = a->x; 44 | prevscheme = scheme[SchemeNorm]; 45 | for (i = 0; i < NUMTAGS; i++) { 46 | #if BAR_HIDEVACANTTAGS_PATCH 47 | /* do not draw vacant tags */ 48 | if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i)) 49 | continue; 50 | #endif // BAR_HIDEVACANTTAGS_PATCH 51 | 52 | icon = tagicon(bar->mon, i); 53 | invert = 0; 54 | w = TEXTW(icon); 55 | drw_settrans(drw, prevscheme, (nxtscheme = scheme[bar->mon->tagset[bar->mon->seltags] & 1 << i ? SchemeSel : SchemeNorm])); 56 | #if BAR_POWERLINE_TAGS_SLASH_PATCH 57 | drw_arrow(drw, x, a->y, plw, a->h, 1, 1); 58 | #else 59 | drw_arrow(drw, x, a->y, plw, a->h, 1, 0); 60 | #endif // BAR_POWERLINE_TAGS_SLASH_PATCH 61 | x += plw; 62 | drw_setscheme(drw, nxtscheme); 63 | drw_text(drw, x, a->y, w, a->h, lrpad / 2, icon, invert, False); 64 | drawindicator(bar->mon, NULL, occ, x, a->y, w, a->h, i, -1, invert, tagindicatortype); 65 | x += w; 66 | prevscheme = nxtscheme; 67 | } 68 | nxtscheme = scheme[SchemeNorm]; 69 | 70 | drw_settrans(drw, prevscheme, nxtscheme); 71 | #if BAR_POWERLINE_TAGS_SLASH_PATCH 72 | drw_arrow(drw, x, a->y, plw, a->h, 1, 1); 73 | #else 74 | drw_arrow(drw, x, a->y, plw, a->h, 1, 0); 75 | #endif // BAR_POWERLINE_TAGS_SLASH_PATCH 76 | return 1; 77 | } 78 | 79 | int 80 | click_pwrl_tags(Bar *bar, Arg *arg, BarArg *a) 81 | { 82 | int i = 0, x = lrpad / 2; 83 | int plw = drw->fonts->h / 2 + 1; 84 | #if BAR_HIDEVACANTTAGS_PATCH 85 | Client *c; 86 | unsigned int occ = 0; 87 | for (c = bar->mon->clients; c; c = c->next) 88 | occ |= c->tags == 255 ? 0 : c->tags; 89 | #endif // BAR_HIDEVACANTTAGS_PATCH 90 | 91 | do { 92 | #if BAR_HIDEVACANTTAGS_PATCH 93 | if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i)) 94 | continue; 95 | #endif // BAR_HIDEVACANTTAGS_PATCH 96 | x += TEXTW(tagicon(bar->mon, i)) + plw; 97 | } while (a->x >= x && ++i < NUMTAGS); 98 | if (i < NUMTAGS) { 99 | arg->ui = 1 << i; 100 | } 101 | return ClkTagBar; 102 | } -------------------------------------------------------------------------------- /patch/ipc/util.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int 5 | normalizepath(const char *path, char **normal) 6 | { 7 | size_t len = strlen(path); 8 | *normal = (char *)malloc((len + 1) * sizeof(char)); 9 | const char *walk = path; 10 | const char *match; 11 | size_t newlen = 0; 12 | 13 | while ((match = strchr(walk, '/'))) { 14 | // Copy everything between match and walk 15 | strncpy(*normal + newlen, walk, match - walk); 16 | newlen += match - walk; 17 | walk += match - walk; 18 | 19 | // Skip all repeating slashes 20 | while (*walk == '/') 21 | walk++; 22 | 23 | // If not last character in path 24 | if (walk != path + len) 25 | (*normal)[newlen++] = '/'; 26 | } 27 | 28 | (*normal)[newlen++] = '\0'; 29 | 30 | // Copy remaining path 31 | strcat(*normal, walk); 32 | newlen += strlen(walk); 33 | 34 | *normal = (char *)realloc(*normal, newlen * sizeof(char)); 35 | 36 | return 0; 37 | } 38 | 39 | int 40 | parentdir(const char *path, char **parent) 41 | { 42 | char *normal; 43 | char *walk; 44 | 45 | normalizepath(path, &normal); 46 | 47 | // Pointer to last '/' 48 | if (!(walk = strrchr(normal, '/'))) { 49 | free(normal); 50 | return -1; 51 | } 52 | 53 | // Get path up to last '/' 54 | size_t len = walk - normal; 55 | *parent = (char *)malloc((len + 1) * sizeof(char)); 56 | 57 | // Copy path up to last '/' 58 | strncpy(*parent, normal, len); 59 | // Add null char 60 | (*parent)[len] = '\0'; 61 | 62 | free(normal); 63 | 64 | return 0; 65 | } 66 | 67 | int 68 | mkdirp(const char *path) 69 | { 70 | char *normal; 71 | char *walk; 72 | size_t normallen; 73 | 74 | normalizepath(path, &normal); 75 | normallen = strlen(normal); 76 | walk = normal; 77 | 78 | while (walk < normal + normallen + 1) { 79 | // Get length from walk to next / 80 | size_t n = strcspn(walk, "/"); 81 | 82 | // Skip path / 83 | if (n == 0) { 84 | walk++; 85 | continue; 86 | } 87 | 88 | // Length of current path segment 89 | size_t curpathlen = walk - normal + n; 90 | char curpath[curpathlen + 1]; 91 | struct stat s; 92 | 93 | // Copy path segment to stat 94 | strncpy(curpath, normal, curpathlen); 95 | strcpy(curpath + curpathlen, ""); 96 | int res = stat(curpath, &s); 97 | 98 | if (res < 0) { 99 | if (errno == ENOENT) { 100 | DEBUG("Making directory %s\n", curpath); 101 | if (mkdir(curpath, 0700) < 0) { 102 | fprintf(stderr, "Failed to make directory %s\n", curpath); 103 | perror(""); 104 | free(normal); 105 | return -1; 106 | } 107 | } else { 108 | fprintf(stderr, "Error statting directory %s\n", curpath); 109 | perror(""); 110 | free(normal); 111 | return -1; 112 | } 113 | } 114 | 115 | // Continue to next path segment 116 | walk += n; 117 | } 118 | 119 | free(normal); 120 | 121 | return 0; 122 | } 123 | 124 | int 125 | nullterminate(char **str, size_t *len) 126 | { 127 | if ((*str)[*len - 1] == '\0') 128 | return 0; 129 | 130 | (*len)++; 131 | *str = (char*)realloc(*str, *len * sizeof(char)); 132 | (*str)[*len - 1] = '\0'; 133 | 134 | return 0; 135 | } 136 | -------------------------------------------------------------------------------- /patch/bar_powerline_status.c: -------------------------------------------------------------------------------- 1 | static Clr **statusscheme; 2 | 3 | int 4 | width_pwrl_status(Bar *bar, BarArg *a) 5 | { 6 | #if BAR_STATUSCMD_PATCH 7 | return widthpowerlinestatus(rawstext); 8 | #else 9 | return widthpowerlinestatus(stext); 10 | #endif // BAR_STATUSCMD_PATCH 11 | } 12 | 13 | #if BAR_EXTRASTATUS_PATCH 14 | int 15 | width_pwrl_status_es(Bar *bar, BarArg *a) 16 | { 17 | #if BAR_STATUSCMD_PATCH 18 | return widthpowerlinestatus(rawestext); 19 | #else 20 | return widthpowerlinestatus(estext); 21 | #endif // BAR_STATUSCMD_PATCH 22 | } 23 | #endif // BAR_EXTRASTATUS_PATCH 24 | 25 | int 26 | draw_pwrl_status(Bar *bar, BarArg *a) 27 | { 28 | #if BAR_STATUSCMD_PATCH 29 | return drawpowerlinestatus(a->x + a->w, rawstext, a); 30 | #else 31 | return drawpowerlinestatus(a->x + a->w, stext, a); 32 | #endif // BAR_STATUSCMD_PATCH 33 | } 34 | 35 | #if BAR_EXTRASTATUS_PATCH 36 | int 37 | draw_pwrl_status_es(Bar *bar, BarArg *a) 38 | { 39 | #if BAR_STATUSCMD_PATCH 40 | return drawpowerlinestatus(a->x + a->w, rawestext, a); 41 | #else 42 | return drawpowerlinestatus(a->x + a->w, estext, a); 43 | #endif // BAR_STATUSCMD_PATCH 44 | } 45 | #endif // BAR_EXTRASTATUS_PATCH 46 | 47 | int 48 | click_pwrl_status(Bar *bar, Arg *arg, BarArg *a) 49 | { 50 | return ClkStatusText; 51 | } 52 | 53 | int 54 | widthpowerlinestatus(char *stext) 55 | { 56 | char status[512]; 57 | int w = 0, i, n = strlen(stext); 58 | int plw = drw->fonts->h / 2 + 1; 59 | char *bs, bp = '|'; 60 | strcpy(status, stext); 61 | 62 | for (i = n, bs = &status[n-1]; i >= 0; i--, bs--) { 63 | if (*bs == '<' || *bs == '/' || *bs == '\\' || *bs == '>' || *bs == '|') { /* block start */ 64 | if (bp != '|') 65 | w += plw; 66 | w += TEXTW(bs+2); 67 | bp = *bs; 68 | *bs = 0; 69 | } 70 | } 71 | if (bp != '|') 72 | w += plw * 2; 73 | 74 | return w; 75 | } 76 | 77 | int 78 | drawpowerlinestatus(int xpos, char *stext, BarArg *barg) 79 | { 80 | char status[512]; 81 | int i, n = strlen(stext), cn = 0; 82 | int x = xpos, w = 0; 83 | int plw = drw->fonts->h / 2 + 1; 84 | char *bs, bp = '|'; 85 | Clr *prevscheme = statusscheme[0], *nxtscheme; 86 | strcpy(status, stext); 87 | 88 | for (i = n, bs = &status[n-1]; i >= 0; i--, bs--) { 89 | if (*bs == '<' || *bs == '/' || *bs == '\\' || *bs == '>' || *bs == '|') { /* block start */ 90 | cn = ((int) *(bs+1)) - 1; 91 | 92 | if (cn < LENGTH(statuscolors)) { 93 | drw_settrans(drw, prevscheme, (nxtscheme = statusscheme[cn])); 94 | } else { 95 | drw_settrans(drw, prevscheme, (nxtscheme = statusscheme[0])); 96 | } 97 | 98 | if (bp != '|') { 99 | drw_arrow(drw, x - plw, barg->y, plw, barg->h, bp == '\\' || bp == '>' ? 1 : 0, bp == '<' ? 0 : 1); 100 | x -= plw; 101 | } 102 | 103 | drw_setscheme(drw, nxtscheme); 104 | w = TEXTW(bs+2); 105 | drw_text(drw, x - w, barg->y, w, barg->h, lrpad / 2, bs+2, 0, False); 106 | x -= w; 107 | 108 | bp = *bs; 109 | *bs = 0; 110 | prevscheme = nxtscheme; 111 | } 112 | } 113 | if (bp != '|') { 114 | drw_settrans(drw, prevscheme, scheme[SchemeNorm]); 115 | drw_arrow(drw, x - plw, barg->y, plw, barg->h, bp == '\\' || bp == '>' ? 1 : 0, bp == '<' ? 0 : 1); 116 | drw_rect(drw, x - 2 * plw, barg->y, plw, barg->h, 1, 1); 117 | x -= plw * 2; 118 | } 119 | 120 | return xpos - x; 121 | } -------------------------------------------------------------------------------- /patch/bar_indicators.c: -------------------------------------------------------------------------------- 1 | /* Indicator properties, you can override these in your config.h if you want. */ 2 | #ifndef TAGSINDICATOR 3 | #define TAGSINDICATOR 1 // 0 = off, 1 = on if >1 client/view tag, 2 = always on 4 | #endif 5 | #ifndef TAGSPX 6 | #define TAGSPX 5 // # pixels for tag grid boxes 7 | #endif 8 | #ifndef TAGSROWS 9 | #define TAGSROWS 3 // # rows in tag grid (9 tags, e.g. 3x3) 10 | #endif 11 | 12 | void 13 | 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) 14 | { 15 | int i, boxw, boxs, indn = 0; 16 | if (!(occ & 1 << tag) || type == INDICATOR_NONE) 17 | return; 18 | 19 | boxs = drw->fonts->h / 9; 20 | boxw = drw->fonts->h / 6 + 2; 21 | if (filled == -1) 22 | filled = m == selmon && m->sel && m->sel->tags & 1 << tag; 23 | 24 | switch (type) { 25 | default: 26 | case INDICATOR_TOP_LEFT_SQUARE: 27 | drw_rect(drw, x + boxs, y + boxs, boxw, boxw, filled, invert); 28 | break; 29 | case INDICATOR_TOP_LEFT_LARGER_SQUARE: 30 | drw_rect(drw, x + boxs + 2, y + boxs+1, boxw+1, boxw+1, filled, invert); 31 | break; 32 | case INDICATOR_TOP_BAR: 33 | drw_rect(drw, x + boxw, y, w - ( 2 * boxw + 1), boxw/2, filled, invert); 34 | break; 35 | case INDICATOR_TOP_BAR_SLIM: 36 | drw_rect(drw, x + boxw, y, w - ( 2 * boxw + 1), 1, 0, invert); 37 | break; 38 | case INDICATOR_BOTTOM_BAR: 39 | drw_rect(drw, x + boxw, y + h - boxw/2, w - ( 2 * boxw + 1), boxw/2, filled, invert); 40 | break; 41 | case INDICATOR_BOTTOM_BAR_SLIM: 42 | drw_rect(drw, x + boxw, y + h - 1, w - ( 2 * boxw + 1), 1, 0, invert); 43 | break; 44 | case INDICATOR_BOX: 45 | drw_rect(drw, x + boxw, y, w - 2 * boxw, h, 0, invert); 46 | break; 47 | case INDICATOR_BOX_WIDER: 48 | drw_rect(drw, x + boxw/2, y, w - boxw, h, 0, invert); 49 | break; 50 | case INDICATOR_BOX_FULL: 51 | drw_rect(drw, x, y, w - 2, h, 0, invert); 52 | break; 53 | case INDICATOR_CLIENT_DOTS: 54 | for (c = m->clients; c; c = c->next) { 55 | if (c->tags & (1 << tag)) { 56 | drw_rect(drw, x, 1 + (indn * 2), m->sel == c ? 6 : 1, 1, 1, invert); 57 | indn++; 58 | } 59 | if (h <= 1 + (indn * 2)) { 60 | indn = 0; 61 | x += 2; 62 | } 63 | } 64 | break; 65 | case INDICATOR_RIGHT_TAGS: 66 | if (!c) 67 | break; 68 | for (i = 0; i < NUMTAGS; i++) { 69 | drw_rect(drw, 70 | ( x + w - 2 - ((NUMTAGS / TAGSROWS) * TAGSPX) 71 | - (i % (NUMTAGS/TAGSROWS)) + ((i % (NUMTAGS / TAGSROWS)) * TAGSPX) 72 | ), 73 | ( 2 + ((i / (NUMTAGS/TAGSROWS)) * TAGSPX) 74 | - ((i / (NUMTAGS/TAGSROWS))) 75 | ), 76 | TAGSPX, TAGSPX, (c->tags >> i) & 1, 0 77 | ); 78 | } 79 | break; 80 | } 81 | } 82 | 83 | void 84 | drawstateindicator(Monitor *m, Client *c, unsigned int occ, int x, int y, int w, int h, unsigned int tag, int filled, int invert) 85 | { 86 | #if FAKEFULLSCREEN_CLIENT_PATCH 87 | if (c->fakefullscreen && c->isfloating) 88 | drawindicator(m, c, occ, x, y, w, h, tag, filled, invert, floatfakefsindicatortype); 89 | else if (c->fakefullscreen) 90 | drawindicator(m, c, occ, x, y, w, h, tag, filled, invert, fakefsindicatortype); 91 | else 92 | #endif // FAKEFULLSCREEN_CLIENT_PATCH 93 | if (c->isfloating) 94 | drawindicator(m, c, occ, x, y, w, h, tag, filled, invert, floatindicatortype); 95 | else 96 | drawindicator(m, c, occ, x, y, w, h, tag, filled, invert, tiledindicatortype); 97 | } 98 | -------------------------------------------------------------------------------- /patch/swallow.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static xcb_connection_t *xcon; 5 | 6 | void 7 | swallow(Client *p, Client *c) 8 | { 9 | if (c->noswallow || c->isterminal) 10 | return; 11 | 12 | detach(c); 13 | detachstack(c); 14 | 15 | setclientstate(c, WithdrawnState); 16 | XUnmapWindow(dpy, p->win); 17 | 18 | p->swallowing = c; 19 | c->mon = p->mon; 20 | 21 | Window w = p->win; 22 | p->win = c->win; 23 | c->win = w; 24 | updatetitle(p); 25 | arrange(p->mon); 26 | XMoveResizeWindow(dpy, p->win, p->x, p->y, p->w, p->h); 27 | configure(p); 28 | updateclientlist(); 29 | } 30 | 31 | void 32 | unswallow(Client *c) 33 | { 34 | c->win = c->swallowing->win; 35 | 36 | free(c->swallowing); 37 | c->swallowing = NULL; 38 | 39 | updatetitle(c); 40 | arrange(c->mon); 41 | XMapWindow(dpy, c->win); 42 | XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); 43 | configure(c); 44 | setclientstate(c, NormalState); 45 | } 46 | 47 | pid_t 48 | winpid(Window w) 49 | { 50 | pid_t result = 0; 51 | 52 | xcb_res_client_id_spec_t spec = {0}; 53 | spec.client = w; 54 | spec.mask = XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID; 55 | 56 | xcb_generic_error_t *e = NULL; 57 | xcb_res_query_client_ids_cookie_t c = xcb_res_query_client_ids(xcon, 1, &spec); 58 | xcb_res_query_client_ids_reply_t *r = xcb_res_query_client_ids_reply(xcon, c, &e); 59 | 60 | if (!r) 61 | return (pid_t)0; 62 | 63 | xcb_res_client_id_value_iterator_t i = xcb_res_query_client_ids_ids_iterator(r); 64 | for (; i.rem; xcb_res_client_id_value_next(&i)) { 65 | spec = i.data->spec; 66 | if (spec.mask & XCB_RES_CLIENT_ID_MASK_LOCAL_CLIENT_PID) { 67 | uint32_t *t = xcb_res_client_id_value_value(i.data); 68 | result = *t; 69 | break; 70 | } 71 | } 72 | 73 | free(r); 74 | 75 | if (result == (pid_t)-1) 76 | result = 0; 77 | return result; 78 | } 79 | 80 | pid_t 81 | getparentprocess(pid_t p) 82 | { 83 | unsigned int v = 0; 84 | 85 | #ifdef __linux__ 86 | FILE *f; 87 | char buf[256]; 88 | snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p); 89 | 90 | if (!(f = fopen(buf, "r"))) 91 | return 0; 92 | 93 | #pragma GCC diagnostic push 94 | #pragma GCC diagnostic ignored "-Wunused-result" 95 | fscanf(f, "%*u %*s %*c %u", &v); 96 | #pragma GCC diagnostic pop 97 | fclose(f); 98 | #endif /* __linux__ */ 99 | 100 | return (pid_t)v; 101 | } 102 | 103 | int 104 | isdescprocess(pid_t p, pid_t c) 105 | { 106 | while (p != c && c != 0) 107 | c = getparentprocess(c); 108 | 109 | return (int)c; 110 | } 111 | 112 | Client * 113 | termforwin(const Client *w) 114 | { 115 | Client *c; 116 | Monitor *m; 117 | 118 | if (!w->pid || w->isterminal) 119 | return NULL; 120 | 121 | c = selmon->sel; 122 | if (c && c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid)) 123 | return c; 124 | 125 | for (m = mons; m; m = m->next) { 126 | for (c = m->clients; c; c = c->next) { 127 | if (c->isterminal && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid)) 128 | return c; 129 | } 130 | } 131 | 132 | return NULL; 133 | } 134 | 135 | Client * 136 | swallowingclient(Window w) 137 | { 138 | Client *c; 139 | Monitor *m; 140 | 141 | for (m = mons; m; m = m->next) { 142 | for (c = m->clients; c; c = c->next) { 143 | if (c->swallowing && c->swallowing->win == w) 144 | return c; 145 | } 146 | } 147 | 148 | return NULL; 149 | } 150 | -------------------------------------------------------------------------------- /tatami.c: -------------------------------------------------------------------------------- 1 | void 2 | tatami(Monitor *m) { 3 | unsigned int i, n, nx, ny, nw, nh, 4 | mats, tc, 5 | tnx, tny, tnw, tnh; 6 | Client *c; 7 | 8 | for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), ++n); 9 | if(n == 0) 10 | return; 11 | 12 | nx = m->wx; 13 | ny = 0; 14 | nw = m->ww; 15 | nh = m->wh; 16 | 17 | c = nexttiled(m->clients); 18 | 19 | if(n != 1) nw = m->ww * m->mfact; 20 | ny = m->wy; 21 | 22 | resize(c, nx, ny, nw - 2 * c->bw, nh - 2 * c->bw, False); 23 | 24 | c = nexttiled(c->next); 25 | 26 | nx += nw; 27 | nw = m->ww - nw; 28 | 29 | if(n>1) 30 | { 31 | 32 | tc = n-1; 33 | mats = tc/5; 34 | 35 | nh/=(mats + (tc % 5 > 0)); 36 | 37 | for(i = 0; c && (i < (tc % 5)); c = nexttiled(c->next)) 38 | { 39 | tnw=nw; 40 | tnx=nx; 41 | tnh=nh; 42 | tny=ny; 43 | switch(tc - (mats*5)) 44 | { 45 | case 1://fill 46 | break; 47 | case 2://up and down 48 | if((i % 5) == 0) //up 49 | tnh/=2; 50 | else if((i % 5) == 1) //down 51 | { 52 | tnh/=2; 53 | tny += nh/2; 54 | } 55 | break; 56 | case 3://bottom, up-left and up-right 57 | if((i % 5) == 0) //up-left 58 | { 59 | tnw = nw/2; 60 | tnh = (2*nh)/3; 61 | } 62 | else if((i % 5) == 1)//up-right 63 | { 64 | tnx += nw/2; 65 | tnw = nw/2; 66 | tnh = (2*nh)/3; 67 | } 68 | else if((i % 5) == 2)//bottom 69 | { 70 | tnh = nh/3; 71 | tny += (2*nh)/3; 72 | } 73 | break; 74 | case 4://bottom, left, right and top 75 | if((i % 5) == 0) //top 76 | { 77 | tnh = (nh)/4; 78 | } 79 | else if((i % 5) == 1)//left 80 | { 81 | tnw = nw/2; 82 | tny += nh/4; 83 | tnh = (nh)/2; 84 | } 85 | else if((i % 5) == 2)//right 86 | { 87 | tnx += nw/2; 88 | tnw = nw/2; 89 | tny += nh/4; 90 | tnh = (nh)/2; 91 | } 92 | else if((i % 5) == 3)//bottom 93 | { 94 | tny += (3*nh)/4; 95 | tnh = (nh)/4; 96 | } 97 | break; 98 | } 99 | ++i; 100 | resize(c, tnx, tny, tnw - 2 * c->bw, tnh - 2 * c->bw, False); 101 | } 102 | 103 | ++mats; 104 | 105 | for(i = 0; c && (mats>0); c = nexttiled(c->next)) { 106 | 107 | if((i%5)==0) 108 | { 109 | --mats; 110 | if(((tc % 5) > 0)||(i>=5)) 111 | ny+=nh; 112 | } 113 | 114 | tnw=nw; 115 | tnx=nx; 116 | tnh=nh; 117 | tny=ny; 118 | 119 | 120 | switch(i % 5) 121 | { 122 | case 0: //top-left-vert 123 | tnw = (nw)/3; 124 | tnh = (nh*2)/3; 125 | break; 126 | case 1: //top-right-hor 127 | tnx += (nw)/3; 128 | tnw = (nw*2)/3; 129 | tnh = (nh)/3; 130 | break; 131 | case 2: //center 132 | tnx += (nw)/3; 133 | tnw = (nw)/3; 134 | tny += (nh)/3; 135 | tnh = (nh)/3; 136 | break; 137 | case 3: //bottom-right-vert 138 | tnx += (nw*2)/3; 139 | tnw = (nw)/3; 140 | tny += (nh)/3; 141 | tnh = (nh*2)/3; 142 | break; 143 | case 4: //(oldest) bottom-left-hor 144 | tnw = (2*nw)/3; 145 | tny += (2*nh)/3; 146 | tnh = (nh)/3; 147 | break; 148 | default: 149 | break; 150 | } 151 | 152 | ++i; 153 | //i%=5; 154 | resize(c, tnx, tny, tnw - 2 * c->bw, tnh - 2 * c->bw, False); 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /patch/keymodes.c: -------------------------------------------------------------------------------- 1 | /* function implementations */ 2 | void 3 | clearcmd(const Arg *arg) 4 | { 5 | unsigned int i; 6 | 7 | for (i = 0; i < LENGTH(cmdkeysym); i++) { 8 | cmdkeysym[i] = 0; 9 | cmdmod[i] = 0; 10 | } 11 | } 12 | 13 | void 14 | grabkeys(void) 15 | { 16 | if (keymode == INSERTMODE) { 17 | grabdefkeys(); 18 | } else if (keymode == COMMANDMODE) { 19 | XUngrabKey(dpy, AnyKey, AnyModifier, root); 20 | XGrabKey(dpy, AnyKey, AnyModifier, root, 21 | True, GrabModeAsync, GrabModeAsync); 22 | } 23 | } 24 | 25 | int 26 | isprotodel(Client *c) 27 | { 28 | int n; 29 | Atom *protocols; 30 | int ret = 0; 31 | 32 | if (XGetWMProtocols(dpy, c->win, &protocols, &n)) { 33 | while (!ret && n--) 34 | ret = protocols[n] == wmatom[WMDelete]; 35 | XFree(protocols); 36 | } 37 | return ret; 38 | } 39 | 40 | 41 | void 42 | keypress(XEvent *e) 43 | { 44 | unsigned int i, j; 45 | Arg a = {0}; 46 | Bool ismatch = False, maybematch = False; 47 | KeySym keysym; 48 | XKeyEvent *ev; 49 | 50 | if (keymode == INSERTMODE) 51 | keydefpress(e); 52 | else if (keymode == COMMANDMODE) { 53 | ev = &e->xkey; 54 | keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); 55 | if (keysym < XK_Shift_L || keysym > XK_Hyper_R) { 56 | for (i = 0; i < LENGTH(cmdkeys); i++) 57 | if (keysym == cmdkeys[i].keysym 58 | && CLEANMASK(cmdkeys[i].mod) == CLEANMASK(ev->state) 59 | && cmdkeys[i].func) { 60 | cmdkeys[i].func(&(cmdkeys[i].arg)); 61 | ismatch = True; 62 | break; 63 | } 64 | if (!ismatch) { 65 | for (j = 0; j < LENGTH(cmdkeysym); j++) 66 | if (cmdkeysym[j] == 0) { 67 | cmdkeysym[j] = keysym; 68 | cmdmod[j] = ev->state; 69 | break; 70 | } 71 | for (i = 0; i < LENGTH(commands); i++) { 72 | for (j = 0; j < LENGTH(cmdkeysym); j++) { 73 | if (cmdkeysym[j] == commands[i].keysym[j] 74 | && CLEANMASK(cmdmod[j]) == CLEANMASK(commands[i].mod[j])) 75 | ismatch = True; 76 | else if (cmdkeysym[j] == 0 77 | && cmdmod[j] == 0) { 78 | ismatch = False; 79 | maybematch = True; 80 | break; 81 | } else { 82 | ismatch = False; 83 | break; 84 | } 85 | } 86 | if (ismatch) { 87 | if (commands[i].func) 88 | commands[i].func(&(commands[i].arg)); 89 | clearcmd(&a); 90 | break; 91 | } 92 | 93 | } 94 | if (!maybematch) 95 | clearcmd(&a); 96 | } 97 | } 98 | } 99 | } 100 | 101 | void 102 | onlyclient(const Arg *arg) 103 | { 104 | Client *c; 105 | XEvent ev; 106 | 107 | if (!selmon->sel) 108 | return; 109 | for (c = selmon->clients; c; c = c->next) { 110 | if (c != selmon->sel && ISVISIBLE(c)) { 111 | if (isprotodel(c)) { 112 | ev.type = ClientMessage; 113 | ev.xclient.window = c->win; 114 | ev.xclient.message_type = wmatom[WMProtocols]; 115 | ev.xclient.format = 32; 116 | ev.xclient.data.l[0] = wmatom[WMDelete]; 117 | ev.xclient.data.l[1] = CurrentTime; 118 | XSendEvent(dpy, c->win, False, NoEventMask, &ev); 119 | } 120 | else { 121 | XGrabServer(dpy); 122 | XSetErrorHandler(xerrordummy); 123 | XSetCloseDownMode(dpy, DestroyAll); 124 | XKillClient(dpy, c->win); 125 | XSync(dpy, False); 126 | XSetErrorHandler(xerror); 127 | XUngrabServer(dpy); 128 | } 129 | } 130 | } 131 | } 132 | 133 | void 134 | setkeymode(const Arg *arg) 135 | { 136 | Arg a = {0}; 137 | 138 | if (!arg) 139 | return; 140 | keymode = arg->ui; 141 | clearcmd(&a); 142 | grabkeys(); 143 | } -------------------------------------------------------------------------------- /drw.h: -------------------------------------------------------------------------------- 1 | /* ___ ______________ _ ____ ___ 2 | * | \/ | _ | _ | | | | \/ | 3 | * | . . | | | | | | | | | | . . | 4 | * | |\/| | | | | | | | |/\| | |\/| | 5 | * | | | \ \_/ | |/ /\ /\ | | | | 6 | * \_| |_/\___/|___/ \/ \/\_| |_/ 7 | * 8 | * MODWM - Modular Dynamic Window Manager. 9 | * --------------------------------------- 10 | * See LICENSE file for copyright and license details. 11 | */ 12 | 13 | #if BAR_PANGO_PATCH 14 | #include 15 | #include 16 | #endif // BAR_PANGO_PATCH 17 | 18 | typedef struct { 19 | Cursor cursor; 20 | } Cur; 21 | 22 | typedef struct Fnt { 23 | Display *dpy; 24 | unsigned int h; 25 | #if BAR_PANGO_PATCH 26 | PangoLayout *layout; 27 | #else 28 | XftFont *xfont; 29 | FcPattern *pattern; 30 | struct Fnt *next; 31 | #endif // BAR_PANGO_PATCH 32 | } Fnt; 33 | 34 | enum { ColFg, ColBg, ColBorder, ColFloat, ColCount }; /* Clr scheme index */ 35 | typedef XftColor Clr; 36 | 37 | typedef struct { 38 | unsigned int w, h; 39 | Display *dpy; 40 | int screen; 41 | Window root; 42 | #if BAR_ALPHA_PATCH 43 | Visual *visual; 44 | unsigned int depth; 45 | Colormap cmap; 46 | #endif // BAR_ALPHA_PATCH 47 | Drawable drawable; 48 | GC gc; 49 | Clr *scheme; 50 | Fnt *fonts; 51 | } Drw; 52 | 53 | /* Drawable abstraction */ 54 | #if BAR_ALPHA_PATCH 55 | Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h, Visual *visual, unsigned int depth, Colormap cmap); 56 | #else 57 | Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); 58 | #endif // BAR_ALPHA_PATCH 59 | void drw_resize(Drw *drw, unsigned int w, unsigned int h); 60 | void drw_free(Drw *drw); 61 | 62 | /* Fnt abstraction */ 63 | #if BAR_PANGO_PATCH 64 | Fnt *drw_font_create(Drw* drw, const char font[]); 65 | void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h, Bool markup); 66 | #else 67 | Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); 68 | void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); 69 | #endif // BAR_PANGO_PATCH 70 | void drw_fontset_free(Fnt* set); 71 | unsigned int drw_fontset_getwidth(Drw *drw, const char *text, Bool markup); 72 | 73 | /* Colorscheme abstraction */ 74 | void drw_clr_create( 75 | Drw *drw, 76 | Clr *dest, 77 | const char *clrname 78 | #if BAR_ALPHA_PATCH 79 | , unsigned int alpha 80 | #endif // BAR_ALPHA_PATCH 81 | ); 82 | Clr *drw_scm_create( 83 | Drw *drw, 84 | char *clrnames[], 85 | #if BAR_ALPHA_PATCH 86 | const unsigned int alphas[], 87 | #endif // BAR_ALPHA_PATCH 88 | size_t clrcount 89 | ); 90 | 91 | /* Cursor abstraction */ 92 | Cur *drw_cur_create(Drw *drw, int shape); 93 | void drw_cur_free(Drw *drw, Cur *cursor); 94 | 95 | /* Drawing context manipulation */ 96 | #if !BAR_PANGO_PATCH 97 | void drw_setfontset(Drw *drw, Fnt *set); 98 | #endif // BAR_PANGO_PATCH 99 | void drw_setscheme(Drw *drw, Clr *scm); 100 | #if BAR_POWERLINE_TAGS_PATCH || BAR_POWERLINE_STATUS_PATCH 101 | void drw_settrans(Drw *drw, Clr *psc, Clr *nsc); 102 | #endif // BAR_POWERLINE_TAGS_PATCH | BAR_POWERLINE_STATUS_PATCH 103 | 104 | /* Drawing functions */ 105 | void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert); 106 | 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); 107 | #if BAR_POWERLINE_TAGS_PATCH || BAR_POWERLINE_STATUS_PATCH 108 | void drw_arrow(Drw *drw, int x, int y, unsigned int w, unsigned int h, int direction, int slash); 109 | #endif // BAR_POWERLINE_TAGS_PATCH | BAR_POWERLINE_STATUS_PATCH 110 | 111 | /* Map functions */ 112 | void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); 113 | -------------------------------------------------------------------------------- /patch/mdpcontrol.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #define MPDHOST "localhost" 9 | #define MPDPORT 6600 10 | 11 | struct mpd_connection *get_conn() 12 | { 13 | struct mpd_connection *conn; 14 | 15 | conn = mpd_connection_new(MPDHOST, MPDPORT, 1000); 16 | 17 | if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) { 18 | fprintf(stderr, "Could not connect to mpd: %s\n", mpd_connection_get_error_message(conn)); 19 | 20 | mpd_connection_free(conn); 21 | return NULL; 22 | } 23 | 24 | return conn; 25 | } 26 | 27 | void mpdchange(const Arg *direction) 28 | { 29 | struct mpd_connection *conn; 30 | 31 | conn = get_conn(); 32 | 33 | if (conn == NULL) { 34 | return; 35 | } 36 | 37 | if (direction->i > 0) { 38 | mpd_run_next(conn); 39 | } 40 | else { 41 | mpd_run_previous(conn); 42 | } 43 | 44 | mpd_connection_free(conn); 45 | } 46 | 47 | char *get_regerror(int errcode, regex_t *compiled) 48 | { 49 | size_t length = regerror(errcode, compiled, NULL, 0); 50 | char *buffer = malloc(length); 51 | (void) regerror(errcode, compiled, buffer, length); 52 | 53 | return buffer; 54 | } 55 | 56 | void mpdcontrol() 57 | { 58 | struct mpd_connection *conn; 59 | struct mpd_status *status; 60 | struct mpd_song *song; 61 | enum mpd_state state; 62 | 63 | const char *filename; 64 | 65 | regex_t expr; 66 | 67 | conn = get_conn(); 68 | 69 | if (conn == NULL) { 70 | return; 71 | } 72 | 73 | status = mpd_run_status(conn); 74 | 75 | if (status == NULL) { 76 | fprintf(stderr, "Could not get mpd status: %s\n", mpd_status_get_error(status)); 77 | 78 | mpd_status_free(status); 79 | mpd_connection_free(conn); 80 | return; 81 | } 82 | 83 | state = mpd_status_get_state(status); 84 | 85 | if (state == MPD_STATE_STOP || state == MPD_STATE_PAUSE) { 86 | mpd_run_play(conn); 87 | mpd_status_free(status); 88 | mpd_connection_free(conn); 89 | } 90 | else if (state != MPD_STATE_UNKNOWN) { //playing some music 91 | song = mpd_run_current_song(conn); 92 | 93 | if (song == NULL){ 94 | fprintf(stderr, "Error fetching current song!\n"); 95 | 96 | mpd_song_free(song); 97 | mpd_status_free(status); 98 | mpd_connection_free(conn); 99 | return; 100 | } 101 | 102 | filename = mpd_song_get_uri(song); 103 | 104 | int errcode = regcomp(&expr, "^[[:alnum:]]+://", REG_EXTENDED|REG_NOSUB); 105 | if (errcode != 0) { 106 | char *err = get_regerror(errcode, &expr); 107 | fprintf(stderr, "Could not compile regexp: %s\n", err); 108 | 109 | mpd_song_free(song); 110 | mpd_status_free(status); 111 | mpd_connection_free(conn); 112 | free(err); 113 | regfree(&expr); 114 | return; 115 | } 116 | 117 | int matchcode = regexec(&expr, filename, 0, NULL, 0); 118 | 119 | if (matchcode == 0) { 120 | if (strstr(filename, "file://") == filename) { //match just at the start of the filename 121 | //this means that mpd is playing a file outside the music_dir, 122 | //but on disk, so we can safely pause 123 | mpd_run_toggle_pause(conn); 124 | } 125 | else { 126 | mpd_run_stop(conn); 127 | } 128 | } 129 | else if (matchcode == REG_NOMATCH) { 130 | mpd_run_toggle_pause(conn); 131 | } 132 | else { 133 | char *err = get_regerror(matchcode, &expr); 134 | fprintf(stderr, "Error while matching regexp: %s\n", err); 135 | 136 | free(err); 137 | } 138 | 139 | regfree(&expr); 140 | mpd_song_free(song); 141 | mpd_status_free(status); 142 | mpd_connection_free(conn); 143 | } 144 | } -------------------------------------------------------------------------------- /patch/layout_fibonacci.c: -------------------------------------------------------------------------------- 1 | #if VANITYGAPS_PATCH 2 | void 3 | fibonacci(Monitor *m, int s) 4 | { 5 | unsigned int i, n; 6 | int nx, ny, nw, nh; 7 | int oh, ov, ih, iv; 8 | int nv, hrest = 0, wrest = 0, r = 1; 9 | Client *c; 10 | 11 | getgaps(m, &oh, &ov, &ih, &iv, &n); 12 | if (n == 0) 13 | return; 14 | 15 | nx = m->wx + ov; 16 | ny = oh; 17 | nw = m->ww - 2*ov; 18 | nh = m->wh - 2*oh; 19 | 20 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) { 21 | if (r) { 22 | if ((i % 2 && (nh - ih) / 2 <= (bh + 2*c->bw)) 23 | || (!(i % 2) && (nw - iv) / 2 <= (bh + 2*c->bw))) { 24 | r = 0; 25 | } 26 | if (r && i < n - 1) { 27 | if (i % 2) { 28 | nv = (nh - ih) / 2; 29 | hrest = nh - 2*nv - ih; 30 | nh = nv; 31 | } else { 32 | nv = (nw - iv) / 2; 33 | wrest = nw - 2*nv - iv; 34 | nw = nv; 35 | } 36 | 37 | if ((i % 4) == 2 && !s) 38 | nx += nw + iv; 39 | else if ((i % 4) == 3 && !s) 40 | ny += nh + ih; 41 | } 42 | 43 | if ((i % 4) == 0) { 44 | if (s) { 45 | ny += nh + ih; 46 | nh += hrest; 47 | } 48 | else { 49 | nh -= hrest; 50 | ny -= nh + ih; 51 | } 52 | } 53 | else if ((i % 4) == 1) { 54 | nx += nw + iv; 55 | nw += wrest; 56 | } 57 | else if ((i % 4) == 2) { 58 | ny += nh + ih; 59 | nh += hrest; 60 | if (i < n - 1) 61 | nw += wrest; 62 | } 63 | else if ((i % 4) == 3) { 64 | if (s) { 65 | nx += nw + iv; 66 | nw -= wrest; 67 | } else { 68 | nw -= wrest; 69 | nx -= nw + iv; 70 | nh += hrest; 71 | } 72 | } 73 | if (i == 0) { 74 | if (n != 1) { 75 | nw = (m->ww - iv - 2*ov) - (m->ww - iv - 2*ov) * (1 - m->mfact); 76 | wrest = 0; 77 | } 78 | ny = m->wy + oh; 79 | } 80 | else if (i == 1) 81 | nw = m->ww - nw - iv - 2*ov; 82 | i++; 83 | } 84 | 85 | resize(c, nx, ny, nw - (2*c->bw), nh - (2*c->bw), False); 86 | } 87 | } 88 | #else 89 | void 90 | fibonacci(Monitor *m, int s) 91 | { 92 | unsigned int i, n; 93 | int nx, ny, nw, nh; 94 | int nv, hrest = 0, wrest = 0, r = 1; 95 | Client *c; 96 | 97 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 98 | if (n == 0) 99 | return; 100 | 101 | nx = m->wx; 102 | ny = m->wy; 103 | nw = m->ww; 104 | nh = m->wh; 105 | 106 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) { 107 | if (r) { 108 | if ((i % 2 && nh / 2 <= (bh + 2*c->bw)) 109 | || (!(i % 2) && nw / 2 <= (bh + 2*c->bw))) { 110 | r = 0; 111 | } 112 | if (r && i < n - 1) { 113 | if (i % 2) { 114 | nv = nh / 2; 115 | hrest = nh - 2*nv; 116 | nh = nv; 117 | } else { 118 | nv = nw / 2; 119 | wrest = nw - 2*nv; 120 | nw = nv; 121 | } 122 | 123 | if ((i % 4) == 2 && !s) 124 | nx += nw; 125 | else if ((i % 4) == 3 && !s) 126 | ny += nh; 127 | } 128 | 129 | if ((i % 4) == 0) { 130 | if (s) { 131 | ny += nh; 132 | nh += hrest; 133 | } 134 | else { 135 | nh -= hrest; 136 | ny -= nh; 137 | } 138 | } 139 | else if ((i % 4) == 1) { 140 | nx += nw; 141 | nw += wrest; 142 | } 143 | else if ((i % 4) == 2) { 144 | ny += nh; 145 | nh += hrest; 146 | if (i < n - 1) 147 | nw += wrest; 148 | } 149 | else if ((i % 4) == 3) { 150 | if (s) { 151 | nx += nw; 152 | nw -= wrest; 153 | } else { 154 | nw -= wrest; 155 | nx -= nw; 156 | nh += hrest; 157 | } 158 | } 159 | if (i == 0) { 160 | if (n != 1) { 161 | nw = m->ww - m->ww * (1 - m->mfact); 162 | wrest = 0; 163 | } 164 | ny = m->wy; 165 | } 166 | else if (i == 1) 167 | nw = m->ww - nw; 168 | i++; 169 | } 170 | 171 | resize(c, nx, ny, nw - (2*c->bw), nh - (2*c->bw), False); 172 | } 173 | } 174 | #endif 175 | 176 | #if FIBONACCI_DWINDLE_LAYOUT 177 | static void 178 | dwindle(Monitor *m) 179 | { 180 | fibonacci(m, 1); 181 | } 182 | #endif 183 | 184 | #if FIBONACCI_SPIRAL_LAYOUT 185 | static void 186 | spiral(Monitor *m) 187 | { 188 | fibonacci(m, 0); 189 | } 190 | #endif 191 | -------------------------------------------------------------------------------- /patch/bar_taggrid.c: -------------------------------------------------------------------------------- 1 | int 2 | width_taggrid(Bar *bar, BarArg *a) 3 | { 4 | return (a->h / 2) * (NUMTAGS / tagrows + ((NUMTAGS % tagrows > 0) ? 1 : 0)) + lrpad; 5 | } 6 | 7 | int 8 | draw_taggrid(Bar *bar, BarArg *a) 9 | { 10 | unsigned int x, y, h, max_x = 0, columns, occ = 0; 11 | int invert, i,j, k; 12 | Client *c; 13 | 14 | for (c = bar->mon->clients; c; c = c->next) 15 | occ |= c->tags; 16 | 17 | max_x = x = a->x + lrpad / 2; 18 | h = a->h / tagrows - 1; 19 | y = a->y; 20 | columns = NUMTAGS / tagrows + ((NUMTAGS % tagrows > 0) ? 1 : 0); 21 | 22 | /* Firstly we will fill the borders of squares */ 23 | XSetForeground(drw->dpy, drw->gc, scheme[SchemeTagsNorm][ColBg].pixel); 24 | XFillRectangle(dpy, drw->drawable, drw->gc, x, y, h*columns + 1, a->h); 25 | 26 | /* We will draw NUMTAGS squares in tagraws raws. */ 27 | for (j = 0, i = 0; j < tagrows; j++) { 28 | x = a->x + lrpad / 2; 29 | for (k = 0; k < columns; k++, i++) { 30 | if (i < NUMTAGS) { 31 | invert = bar->mon->tagset[bar->mon->seltags] & 1 << i ? 0 : 1; 32 | 33 | /* Select active color for current square */ 34 | XSetForeground(drw->dpy, drw->gc, !invert ? scheme[SchemeTagsSel][ColBg].pixel : 35 | scheme[SchemeTagsNorm][ColFg].pixel); 36 | XFillRectangle(dpy, drw->drawable, drw->gc, x+1, y+1, h-1, h-1); 37 | 38 | /* Mark square if tag has client */ 39 | if (occ & 1 << i) { 40 | XSetForeground(drw->dpy, drw->gc, !invert ? scheme[SchemeTagsSel][ColFg].pixel : 41 | scheme[SchemeTagsNorm][ColBg].pixel); 42 | XFillRectangle(dpy, drw->drawable, drw->gc, x + 1, y + 1, 43 | h / 2, h / 2); 44 | } 45 | } else { 46 | XSetForeground(drw->dpy, drw->gc, scheme[SchemeTagsNorm][ColBg].pixel); 47 | XFillRectangle(dpy, drw->drawable, drw->gc, x+1, y+1, h-1, h); 48 | } 49 | x += h; 50 | if (x > max_x) { 51 | max_x = x; 52 | } 53 | } 54 | y += h; 55 | } 56 | return 1; 57 | } 58 | 59 | int 60 | click_taggrid(Bar *bar, Arg *arg, BarArg *a) 61 | { 62 | unsigned int i, h, columns; 63 | 64 | h = a->h / tagrows - 1; 65 | columns = NUMTAGS / tagrows + ((NUMTAGS % tagrows > 0) ? 1 : 0); 66 | i = (a->x - lrpad / 2) / h + columns * (a->y / h); 67 | if (i >= NUMTAGS) { 68 | i = NUMTAGS - 1; 69 | } 70 | arg->ui = 1 << i; 71 | return ClkTagBar; 72 | } 73 | 74 | void 75 | switchtag(const Arg *arg) 76 | { 77 | unsigned int columns; 78 | unsigned int new_tagset = 0; 79 | unsigned int pos, i; 80 | int col, row; 81 | Arg new_arg; 82 | 83 | columns = NUMTAGS / tagrows + ((NUMTAGS % tagrows > 0) ? 1 : 0); 84 | 85 | for (i = 0; i < NUMTAGS; ++i) { 86 | if (!(selmon->tagset[selmon->seltags] & 1 << i)) { 87 | continue; 88 | } 89 | pos = i; 90 | row = pos / columns; 91 | col = pos % columns; 92 | if (arg->ui & SWITCHTAG_UP) { /* UP */ 93 | row --; 94 | if (row < 0) { 95 | row = tagrows - 1; 96 | } 97 | do { 98 | pos = row * columns + col; 99 | row --; 100 | } while (pos >= NUMTAGS); 101 | } 102 | if (arg->ui & SWITCHTAG_DOWN) { /* DOWN */ 103 | row ++; 104 | if (row >= tagrows) { 105 | row = 0; 106 | } 107 | pos = row * columns + col; 108 | if (pos >= NUMTAGS) { 109 | row = 0; 110 | } 111 | pos = row * columns + col; 112 | } 113 | if (arg->ui & SWITCHTAG_LEFT) { /* LEFT */ 114 | col --; 115 | if (col < 0) { 116 | col = columns - 1; 117 | } 118 | do { 119 | pos = row * columns + col; 120 | col --; 121 | } while (pos >= NUMTAGS); 122 | } 123 | if (arg->ui & SWITCHTAG_RIGHT) { /* RIGHT */ 124 | col ++; 125 | if (col >= columns) { 126 | col = 0; 127 | } 128 | pos = row * columns + col; 129 | if (pos >= NUMTAGS) { 130 | col = 0; 131 | pos = row * columns + col; 132 | } 133 | } 134 | new_tagset |= 1 << pos; 135 | } 136 | new_arg.ui = new_tagset; 137 | if (arg->ui & SWITCHTAG_TOGGLETAG) { 138 | toggletag(&new_arg); 139 | } 140 | if (arg->ui & SWITCHTAG_TAG) { 141 | tag(&new_arg); 142 | } 143 | if (arg->ui & SWITCHTAG_VIEW) { 144 | view (&new_arg); 145 | } 146 | if (arg->ui & SWITCHTAG_TOGGLEVIEW) { 147 | toggleview (&new_arg); 148 | } 149 | } -------------------------------------------------------------------------------- /patch/vanitygaps.c: -------------------------------------------------------------------------------- 1 | /* Settings */ 2 | #if !PERTAG_PATCH 3 | static int enablegaps = 1; 4 | #endif // PERTAG_PATCH 5 | 6 | static void 7 | setgaps(int oh, int ov, int ih, int iv) 8 | { 9 | if (oh < 0) oh = 0; 10 | if (ov < 0) ov = 0; 11 | if (ih < 0) ih = 0; 12 | if (iv < 0) iv = 0; 13 | 14 | selmon->gappoh = oh; 15 | selmon->gappov = ov; 16 | selmon->gappih = ih; 17 | selmon->gappiv = iv; 18 | arrange(selmon); 19 | } 20 | 21 | #if IPC_PATCH || DWMC_PATCH 22 | /* External function that takes one integer and splits it 23 | * into four gap values: 24 | * - outer horizontal (oh) 25 | * - outer vertical (ov) 26 | * - inner horizontal (ih) 27 | * - inner vertical (iv) 28 | * 29 | * Each value is represented as one byte with the uppermost 30 | * bit of each byte indicating whether or not to keep the 31 | * current value. 32 | * 33 | * Example: 34 | * 35 | * 10000000 10000000 00001111 00001111 36 | * | | | | 37 | * + keep oh + keep ov + ih 15px + iv 15px 38 | * 39 | * This gives an int of: 40 | * 10000000100000000000111100001111 = 2155876111 41 | * 42 | * Thus this command should set inner gaps to 15: 43 | * xsetroot -name "fsignal:setgaps i 2155876111" 44 | */ 45 | static void 46 | setgapsex(const Arg *arg) 47 | { 48 | int oh = selmon->gappoh; 49 | int ov = selmon->gappov; 50 | int ih = selmon->gappih; 51 | int iv = selmon->gappiv; 52 | 53 | if (!(arg->i & (1 << 31))) 54 | oh = (arg->i & 0x7f000000) >> 24; 55 | if (!(arg->i & (1 << 23))) 56 | ov = (arg->i & 0x7f0000) >> 16; 57 | if (!(arg->i & (1 << 15))) 58 | ih = (arg->i & 0x7f00) >> 8; 59 | if (!(arg->i & (1 << 7))) 60 | iv = (arg->i & 0x7f); 61 | 62 | /* Auto enable gaps if disabled */ 63 | #if PERTAG_PATCH 64 | if (!selmon->pertag->enablegaps[selmon->pertag->curtag]) 65 | selmon->pertag->enablegaps[selmon->pertag->curtag] = 1; 66 | #else 67 | if (!enablegaps) 68 | enablegaps = 1; 69 | #endif // PERTAG_PATCH 70 | 71 | setgaps(oh, ov, ih, iv); 72 | } 73 | #endif // IPC_PATCH | DWMC_PATCH 74 | 75 | static void 76 | togglegaps(const Arg *arg) 77 | { 78 | #if PERTAG_PATCH 79 | selmon->pertag->enablegaps[selmon->pertag->curtag] = !selmon->pertag->enablegaps[selmon->pertag->curtag]; 80 | #else 81 | enablegaps = !enablegaps; 82 | #endif // PERTAG_PATCH 83 | arrange(NULL); 84 | } 85 | 86 | static void 87 | defaultgaps(const Arg *arg) 88 | { 89 | setgaps(gappoh, gappov, gappih, gappiv); 90 | } 91 | 92 | static void 93 | incrgaps(const Arg *arg) 94 | { 95 | setgaps( 96 | selmon->gappoh + arg->i, 97 | selmon->gappov + arg->i, 98 | selmon->gappih + arg->i, 99 | selmon->gappiv + arg->i 100 | ); 101 | } 102 | 103 | static void 104 | incrigaps(const Arg *arg) 105 | { 106 | setgaps( 107 | selmon->gappoh, 108 | selmon->gappov, 109 | selmon->gappih + arg->i, 110 | selmon->gappiv + arg->i 111 | ); 112 | } 113 | 114 | static void 115 | incrogaps(const Arg *arg) 116 | { 117 | setgaps( 118 | selmon->gappoh + arg->i, 119 | selmon->gappov + arg->i, 120 | selmon->gappih, 121 | selmon->gappiv 122 | ); 123 | } 124 | 125 | static void 126 | incrohgaps(const Arg *arg) 127 | { 128 | setgaps( 129 | selmon->gappoh + arg->i, 130 | selmon->gappov, 131 | selmon->gappih, 132 | selmon->gappiv 133 | ); 134 | } 135 | 136 | static void 137 | incrovgaps(const Arg *arg) 138 | { 139 | setgaps( 140 | selmon->gappoh, 141 | selmon->gappov + arg->i, 142 | selmon->gappih, 143 | selmon->gappiv 144 | ); 145 | } 146 | 147 | static void 148 | incrihgaps(const Arg *arg) 149 | { 150 | setgaps( 151 | selmon->gappoh, 152 | selmon->gappov, 153 | selmon->gappih + arg->i, 154 | selmon->gappiv 155 | ); 156 | } 157 | 158 | static void 159 | incrivgaps(const Arg *arg) 160 | { 161 | setgaps( 162 | selmon->gappoh, 163 | selmon->gappov, 164 | selmon->gappih, 165 | selmon->gappiv + arg->i 166 | ); 167 | } 168 | 169 | #if DRAGMFACT_PATCH || CENTEREDMASTER_LAYOUT || CENTEREDFLOATINGMASTER_LAYOUT || COLUMNS_LAYOUT || DECK_LAYOUT || FIBONACCI_DWINDLE_LAYOUT || FIBONACCI_SPIRAL_LAYOUT || GAPPLESSGRID_LAYOUT || NROWGRID_LAYOUT || HORIZGRID_LAYOUT || BSTACK_LAYOUT || BSTACKHORIZ_LAYOUT || GRIDMODE_LAYOUT || FLEXTILE_DELUXE_LAYOUT || TILE_LAYOUT || (VANITYGAPS_MONOCLE_PATCH && MONOCLE_LAYOUT) 170 | static void 171 | getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc) 172 | { 173 | unsigned int n, oe, ie; 174 | #if PERTAG_PATCH 175 | oe = ie = selmon->pertag->enablegaps[selmon->pertag->curtag]; 176 | #else 177 | oe = ie = enablegaps; 178 | #endif // PERTAG_PATCH 179 | Client *c; 180 | 181 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 182 | if (smartgaps && n == 1) { 183 | oe = 0; // outer gaps disabled when only one client 184 | } 185 | 186 | *oh = m->gappoh*oe; // outer horizontal gap 187 | *ov = m->gappov*oe; // outer vertical gap 188 | *ih = m->gappih*ie; // inner horizontal gap 189 | *iv = m->gappiv*ie; // inner vertical gap 190 | *nc = n; // number of clients 191 | } 192 | #endif 193 | -------------------------------------------------------------------------------- /patch/layout_centeredmaster.c: -------------------------------------------------------------------------------- 1 | void 2 | centeredmaster(Monitor *m) 3 | { 4 | unsigned int i, n; 5 | int mx = 0, my = 0, mh = 0, mw = 0; 6 | int lx = 0, ly = 0, lw = 0, lh = 0; 7 | int rx = 0, ry = 0, rw = 0, rh = 0; 8 | float mfacts = 0, lfacts = 0, rfacts = 0; 9 | int mtotal = 0, ltotal = 0, rtotal = 0; 10 | int mrest = 0, lrest = 0, rrest = 0; 11 | Client *c; 12 | 13 | #if VANITYGAPS_PATCH 14 | int oh, ov, ih, iv; 15 | getgaps(m, &oh, &ov, &ih, &iv, &n); 16 | #else 17 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 18 | #endif // VANITYGAPS_PATCH 19 | 20 | if (n == 0) 21 | return; 22 | 23 | /* initialize areas */ 24 | #if VANITYGAPS_PATCH 25 | mx = m->wx + ov; 26 | my = m->wy + oh; 27 | mh = m->wh - 2*oh - ih * ((!m->nmaster ? n : MIN(n, m->nmaster)) - 1); 28 | mw = m->ww - 2*ov; 29 | lh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - 1); 30 | rh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - ((n - m->nmaster) % 2 ? 0 : 1)); 31 | 32 | if (m->nmaster && n > m->nmaster) { 33 | /* go mfact box in the center if more than nmaster clients */ 34 | if (n - m->nmaster > 1) { 35 | /* ||<-S->|<---M--->|<-S->|| */ 36 | mw = (m->ww - 2*ov - 2*iv) * m->mfact; 37 | lw = (m->ww - mw - 2*ov - 2*iv) / 2; 38 | mx += lw + iv; 39 | } else { 40 | /* ||<---M--->|<-S->|| */ 41 | mw = (mw - iv) * m->mfact; 42 | lw = m->ww - mw - iv - 2*ov; 43 | } 44 | rw = lw; 45 | lx = m->wx + ov; 46 | ly = m->wy + oh; 47 | rx = mx + mw + iv; 48 | ry = m->wy + oh; 49 | } 50 | #else 51 | mx = m->wx; 52 | my = m->wy; 53 | mh = m->wh; 54 | mw = m->ww; 55 | lh = m->wh; 56 | rh = m->wh; 57 | 58 | if (m->nmaster && n > m->nmaster) { 59 | /* go mfact box in the center if more than nmaster clients */ 60 | if (n - m->nmaster > 1) { 61 | /* ||<-S->|<---M--->|<-S->|| */ 62 | mw = m->ww * m->mfact; 63 | lw = (m->ww - mw) / 2; 64 | mx += lw; 65 | } else { 66 | /* ||<---M--->|<-S->|| */ 67 | mw = mw * m->mfact; 68 | lw = m->ww - mw; 69 | } 70 | rw = lw; 71 | lx = m->wx; 72 | ly = m->wy; 73 | rx = mx + mw; 74 | ry = m->wy; 75 | } 76 | #endif // VANITYGAPS_PATCH 77 | 78 | /* calculate facts */ 79 | #if CFACTS_PATCH 80 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) { 81 | if (!m->nmaster || n < m->nmaster) 82 | mfacts += c->cfact; // total factor of master area 83 | else if ((n - m->nmaster) % 2) 84 | lfacts += c->cfact; // total factor of left hand stack area 85 | else 86 | rfacts += c->cfact; // total factor of right hand stack area 87 | } 88 | 89 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) 90 | if (!m->nmaster || n < m->nmaster) 91 | mtotal += mh / mfacts; 92 | else if ((n - m->nmaster) % 2) 93 | ltotal += lh * (c->cfact / lfacts); 94 | else 95 | rtotal += rh * (c->cfact / rfacts); 96 | #else 97 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) { 98 | if (!m->nmaster || n < m->nmaster) 99 | mfacts += 1; 100 | else if ((n - m->nmaster) % 2) 101 | lfacts += 1; // total factor of left hand stack area 102 | else 103 | rfacts += 1; // total factor of right hand stack area 104 | } 105 | 106 | for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) 107 | if (!m->nmaster || n < m->nmaster) 108 | mtotal += mh / mfacts; 109 | else if ((n - m->nmaster) % 2) 110 | ltotal += lh / lfacts; 111 | else 112 | rtotal += rh / rfacts; 113 | #endif // CFACTS_PATCH 114 | 115 | mrest = mh - mtotal; 116 | lrest = lh - ltotal; 117 | rrest = rh - rtotal; 118 | 119 | for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { 120 | if (!m->nmaster || i < m->nmaster) { 121 | /* nmaster clients are stacked vertically, in the center of the screen */ 122 | #if CFACTS_PATCH 123 | resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) * c->cfact + (i < mrest ? 1 : 0) - (2*c->bw), 0); 124 | #else 125 | resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); 126 | #endif // CFACTS_PATCH 127 | #if VANITYGAPS_PATCH 128 | my += HEIGHT(c) + ih; 129 | #else 130 | my += HEIGHT(c); 131 | #endif 132 | } else { 133 | /* stack clients are stacked vertically */ 134 | if ((i - m->nmaster) % 2 ) { 135 | #if CFACTS_PATCH 136 | resize(c, lx, ly, lw - (2*c->bw), (lh / lfacts) * c->cfact + ((i - 2*m->nmaster) < 2*lrest ? 1 : 0) - (2*c->bw), 0); 137 | #else 138 | resize(c, lx, ly, lw - (2*c->bw), (lh / lfacts) + ((i - 2*m->nmaster) < 2*lrest ? 1 : 0) - (2*c->bw), 0); 139 | #endif // CFACTS_PATCH 140 | #if VANITYGAPS_PATCH 141 | ly += HEIGHT(c) + ih; 142 | #else 143 | ly += HEIGHT(c); 144 | #endif 145 | } else { 146 | #if CFACTS_PATCH 147 | resize(c, rx, ry, rw - (2*c->bw), (rh / rfacts) * c->cfact + ((i - 2*m->nmaster) < 2*rrest ? 1 : 0) - (2*c->bw), 0); 148 | #else 149 | resize(c, rx, ry, rw - (2*c->bw), (rh / rfacts) + ((i - 2*m->nmaster) < 2*rrest ? 1 : 0) - (2*c->bw), 0); 150 | #endif // CFACTS_PATCH 151 | #if VANITYGAPS_PATCH 152 | ry += HEIGHT(c) + ih; 153 | #else 154 | ry += HEIGHT(c); 155 | #endif 156 | } 157 | } 158 | } 159 | } --------------------------------------------------------------------------------