From 8a327dc6f395b6cb54fc49eebff93b4399e4b4dc Mon Sep 17 00:00:00 2001 From: pim-wtf Date: Thu, 16 Feb 2023 10:19:30 +0100 Subject: [PATCH] added t480s config --- t480s/dwm/.Xresources | 61 + t480s/dwm/dwm/Makefile | 51 + t480s/dwm/dwm/config.def.h | 286 ++ t480s/dwm/dwm/config.h | 286 ++ t480s/dwm/dwm/config.mk | 39 + t480s/dwm/dwm/drw.c | 527 +++ t480s/dwm/dwm/drw.h | 63 + t480s/dwm/dwm/drw.o | Bin 0 -> 15968 bytes t480s/dwm/dwm/dwm | Bin 0 -> 136672 bytes t480s/dwm/dwm/dwm.1 | 179 + t480s/dwm/dwm/dwm.c | 3844 +++++++++++++++++++++ t480s/dwm/dwm/dwm.o | Bin 0 -> 148568 bytes t480s/dwm/dwm/dwm.png | Bin 0 -> 373 bytes t480s/dwm/dwm/fibonacci.c | 66 + t480s/dwm/dwm/functions.h | 30 + t480s/dwm/dwm/gaplessgrid.c | 35 + t480s/dwm/dwm/movestack.c | 49 + t480s/dwm/dwm/themes/catppuccin.h | 12 + t480s/dwm/dwm/themes/dracula.h | 12 + t480s/dwm/dwm/themes/gruvbox-dark.h | 12 + t480s/dwm/dwm/themes/nord.h | 12 + t480s/dwm/dwm/themes/onedark.h | 12 + t480s/dwm/dwm/transient.c | 42 + t480s/dwm/dwm/util.c | 36 + t480s/dwm/dwm/util.h | 8 + t480s/dwm/dwm/util.o | Bin 0 -> 2264 bytes t480s/dwm/dwm/vanitygaps.c | 795 +++++ t480s/dwm/rofi/config.rasi | 98 + t480s/dwm/rofi/themes/dracula.rasi | 11 + t480s/dwm/rofi/themes/everblush.rasi | 11 + t480s/dwm/rofi/themes/forest.rasi | 11 + t480s/dwm/rofi/themes/gruv.rasi | 11 + t480s/dwm/rofi/themes/nord.rasi | 11 + t480s/dwm/rofi/themes/onedark.rasi | 11 + t480s/dwm/scripts/bar.sh | 63 + t480s/dwm/scripts/bar_themes/catppuccin | 11 + t480s/dwm/scripts/bar_themes/dracula | 11 + t480s/dwm/scripts/bar_themes/gruvbox-dark | 11 + t480s/dwm/scripts/bar_themes/nord | 11 + t480s/dwm/scripts/bar_themes/onedark | 11 + t480s/dwm/scripts/fetch | 77 + t480s/dwm/scripts/license/fetch.md | 21 + t480s/dwm/scripts/run.sh | 10 + t480s/fish/config.fish | 1 + t480s/fish/fish_variables | 35 + t480s/fish/functions/fish_prompt.fish | 6 + t480s/kitty/kitty.conf | 59 + t480s/nvim/.netrwhist | 6 + t480s/nvim/init.vim | 54 + 49 files changed, 7008 insertions(+) create mode 100644 t480s/dwm/.Xresources create mode 100644 t480s/dwm/dwm/Makefile create mode 100644 t480s/dwm/dwm/config.def.h create mode 100644 t480s/dwm/dwm/config.h create mode 100644 t480s/dwm/dwm/config.mk create mode 100644 t480s/dwm/dwm/drw.c create mode 100644 t480s/dwm/dwm/drw.h create mode 100644 t480s/dwm/dwm/drw.o create mode 100755 t480s/dwm/dwm/dwm create mode 100644 t480s/dwm/dwm/dwm.1 create mode 100644 t480s/dwm/dwm/dwm.c create mode 100644 t480s/dwm/dwm/dwm.o create mode 100644 t480s/dwm/dwm/dwm.png create mode 100644 t480s/dwm/dwm/fibonacci.c create mode 100644 t480s/dwm/dwm/functions.h create mode 100644 t480s/dwm/dwm/gaplessgrid.c create mode 100644 t480s/dwm/dwm/movestack.c create mode 100644 t480s/dwm/dwm/themes/catppuccin.h create mode 100644 t480s/dwm/dwm/themes/dracula.h create mode 100644 t480s/dwm/dwm/themes/gruvbox-dark.h create mode 100644 t480s/dwm/dwm/themes/nord.h create mode 100644 t480s/dwm/dwm/themes/onedark.h create mode 100644 t480s/dwm/dwm/transient.c create mode 100644 t480s/dwm/dwm/util.c create mode 100644 t480s/dwm/dwm/util.h create mode 100644 t480s/dwm/dwm/util.o create mode 100644 t480s/dwm/dwm/vanitygaps.c create mode 100644 t480s/dwm/rofi/config.rasi create mode 100644 t480s/dwm/rofi/themes/dracula.rasi create mode 100644 t480s/dwm/rofi/themes/everblush.rasi create mode 100644 t480s/dwm/rofi/themes/forest.rasi create mode 100644 t480s/dwm/rofi/themes/gruv.rasi create mode 100644 t480s/dwm/rofi/themes/nord.rasi create mode 100644 t480s/dwm/rofi/themes/onedark.rasi create mode 100755 t480s/dwm/scripts/bar.sh create mode 100755 t480s/dwm/scripts/bar_themes/catppuccin create mode 100755 t480s/dwm/scripts/bar_themes/dracula create mode 100755 t480s/dwm/scripts/bar_themes/gruvbox-dark create mode 100755 t480s/dwm/scripts/bar_themes/nord create mode 100755 t480s/dwm/scripts/bar_themes/onedark create mode 100755 t480s/dwm/scripts/fetch create mode 100644 t480s/dwm/scripts/license/fetch.md create mode 100755 t480s/dwm/scripts/run.sh create mode 100644 t480s/fish/config.fish create mode 100644 t480s/fish/fish_variables create mode 100644 t480s/fish/functions/fish_prompt.fish create mode 100644 t480s/kitty/kitty.conf create mode 100644 t480s/nvim/.netrwhist create mode 100644 t480s/nvim/init.vim diff --git a/t480s/dwm/.Xresources b/t480s/dwm/.Xresources new file mode 100644 index 0000000..dad9d10 --- /dev/null +++ b/t480s/dwm/.Xresources @@ -0,0 +1,61 @@ +Xft.antialias: 1 +Xft.hinting: 1 +Xft.autohint: 0 +Xft.hintstyle: hintslight +Xft.rgba: rgb +Xft.lcdfilter: lcddefault + +! window padding +st.borderpx: 20 + +!-- values between 0.1 - 1.0 --! + +st.alpha: 1.0 +st.font: JetBrainsMono Nerd Font:style:medium:pixelsize=15 + +#define base00 #282c34 +#define base01 #353b45 +#define base02 #3e4451 +#define base03 #545862 +#define base04 #565c64 +#define base05 #abb2bf +#define base06 #b6bdca +#define base07 #c8ccd4 +#define base08 #e06c75 +#define base09 #d19a66 +#define base0A #e5c07b +#define base0B #98c379 +#define base0C #56b6c2 +#define base0D #61afef +#define base0E #c678dd +#define base0F #be5046 + +*foreground: base07 +*background: #1e222a +*cursorColor: base05 + +*color0: base00 +*color1: base08 +*color2: base0B +*color3: base0A +*color4: base0D +*color5: base0E +*color6: base0C +*color7: base05 + +*color8: base03 +*color9: base08 +*color10: base0B +*color11: base0A +*color12: base0D +*color13: base0E +*color14: base0C +*color15: base07 + +! just remove this if you dont use my tabbed + +tabbed.selfgcolor: #d6d8eb +tabbed.selbgcolor: #1e222a + +tabbed.normfgcolor: #9294a8 +tabbed.normbgcolor: #282c34 diff --git a/t480s/dwm/dwm/Makefile b/t480s/dwm/dwm/Makefile new file mode 100644 index 0000000..c05dbdd --- /dev/null +++ b/t480s/dwm/dwm/Makefile @@ -0,0 +1,51 @@ +# dwm - dynamic window manager +# See LICENSE file for copyright and license details. + +include config.mk + +SRC = drw.c dwm.c util.c +OBJ = ${SRC:.c=.o} + +all: options dwm + +options: + @echo dwm build options: + @echo "CFLAGS = ${CFLAGS}" + @echo "LDFLAGS = ${LDFLAGS}" + @echo "CC = ${CC}" + +.c.o: + ${CC} -c ${CFLAGS} $< + +${OBJ}: config.h config.mk + +config.h: + cp config.def.h $@ + +dwm: ${OBJ} + ${CC} -o $@ ${OBJ} ${LDFLAGS} + +clean: + rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz config.h + +dist: clean + mkdir -p dwm-${VERSION} + cp -R LICENSE Makefile README config.def.h config.mk\ + dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION} + tar -cf dwm-${VERSION}.tar dwm-${VERSION} + gzip dwm-${VERSION}.tar + rm -rf dwm-${VERSION} + +install: all + mkdir -p ${DESTDIR}${PREFIX}/bin + cp -f dwm ${DESTDIR}${PREFIX}/bin + chmod 755 ${DESTDIR}${PREFIX}/bin/dwm + mkdir -p ${DESTDIR}${MANPREFIX}/man1 + sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1 + chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1 + +uninstall: + rm -f ${DESTDIR}${PREFIX}/bin/dwm\ + ${DESTDIR}${MANPREFIX}/man1/dwm.1 + +.PHONY: all options clean dist install uninstall diff --git a/t480s/dwm/dwm/config.def.h b/t480s/dwm/dwm/config.def.h new file mode 100644 index 0000000..c50d2ae --- /dev/null +++ b/t480s/dwm/dwm/config.def.h @@ -0,0 +1,286 @@ +/* See LICENSE file for copyright and license details. */ + +#include + +/* appearance */ +static const unsigned int borderpx = 0; /* border pixel of windows */ +static const unsigned int default_border = 0; /* to switch back to default border after dynamic border resizing via keybinds */ +static const unsigned int snap = 32; /* snap pixel */ +static const unsigned int gappih = 10; /* horiz inner gap between windows */ +static const unsigned int gappiv = 10; /* vert inner gap between windows */ +static const unsigned int gappoh = 10; /* horiz outer gap between windows and screen edge */ +static const unsigned int gappov = 10; /* vert outer gap between windows and screen edge */ +static const int smartgaps = 0; /* 1 means no outer gap when there is only one window */ +static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */ +static const unsigned int systrayspacing = 2; /* systray spacing */ +static const int systraypinningfailfirst = 1; /* 1: if pinning fails,display systray on the 1st monitor,False: display systray on last monitor*/ +static const int showsystray = 1; /* 0 means no systray */ +static const int showbar = 1; /* 0 means no bar */ +static const int showtab = showtab_auto; +static const int toptab = 1; /* 0 means bottom tab */ +static const int floatbar = 1;/* 1 means the bar will float(don't have padding),0 means the bar have padding */ +static const int topbar = 1; /* 0 means bottom bar */ +static const int horizpadbar = 5; +static const int vertpadbar = 11; +static const int vertpadtab = 35; +static const int horizpadtabi = 15; +static const int horizpadtabo = 15; +static const int scalepreview = 4; +static const int tag_preview = 0; /* 1 means enable, 0 is off */ +static const int colorfultag = 1; /* 0 means use SchemeSel for selected non vacant tag */ +static const char *upvol[] = { "/usr/bin/pactl", "set-sink-volume", "0", "+5%", NULL }; +static const char *downvol[] = { "/usr/bin/pactl", "set-sink-volume", "0", "-5%", NULL }; +static const char *mutevol[] = { "/usr/bin/pactl", "set-sink-mute", "0", "toggle", NULL }; +static const char *light_up[] = {"/usr/bin/light", "-A", "5", NULL}; +static const char *light_down[] = {"/usr/bin/light", "-U", "5", NULL}; +static const int new_window_attach_on_end = 0; /* 1 means the new window will attach on the end; 0 means the new window will attach on the front,default is front */ +#define ICONSIZE 19 /* icon size */ +#define ICONSPACING 8 /* space between icon and title */ + +static const char *fonts[] = {"Noto Sans Mono:style:medium:size=12" ,"JetBrainsMono Nerd Font Mono:style:medium:size=19", + "Material Design Icons Desktop:size=11" }; + +// theme +#include "themes/gruvbox-dark.h" + +static const char *colors[][3] = { + /* fg bg border */ + [SchemeNorm] = { gray3, black, gray2 }, + [SchemeSel] = { gray4, blue, blue }, + [SchemeTitle] = { white, black, black }, // active window title + [TabSel] = { blue, gray2, black }, + [TabNorm] = { gray3, black, black }, + [SchemeTag] = { gray3, black, black }, + [SchemeTag1] = { blue, black, black }, + [SchemeTag2] = { red, black, black }, + [SchemeTag3] = { orange, black, black }, + [SchemeTag4] = { green, black, black }, + [SchemeTag5] = { pink, black, black }, + [SchemeLayout] = { green, black, black }, + [SchemeBtnPrev] = { green, black, black }, + [SchemeBtnNext] = { yellow, black, black }, + [SchemeBtnClose] = { red, black, black }, +}; + +/* tagging */ +static char *tags[] = {"", "", "", "", "", "", ""}; + +static const char* eww[] = { "eww", "open" , "eww", NULL }; + +static const Launcher launchers[] = { + /* command name to display */ + { eww, "" }, +}; + +static const int tagschemes[] = { + SchemeTag1, SchemeTag2, SchemeTag3, SchemeTag4, SchemeTag5 +}; + +static const unsigned int ulinepad = 5; /* horizontal padding between the underline and tag */ +static const unsigned int ulinestroke = 2; /* thickness / height of the underline */ +static const unsigned int ulinevoffset = 0; /* how far above the bottom of the bar the line should appear */ +static const int ulineall = 0; /* 1 to show underline on all tags, 0 for just the active ones */ + +static const Rule rules[] = { + /* xprop(1): + * WM_CLASS(STRING) = instance, class + * WM_NAME(STRING) = title + */ + /* class instance title tags mask iscentered isfloating monitor */ + { "Gimp", NULL, NULL, 0, 0, 1, -1 }, + { "Firefox", NULL, NULL, 1 << 8, 0, 0, -1 }, + { "eww", NULL, NULL, 0, 0, 1, -1 }, +}; + +/* layout(s) */ +static const float mfact = 0.50; /* factor of master area size [0.05..0.95] */ +static const int nmaster = 1; /* number of clients in master area */ +static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */ +static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ + +#define FORCE_VSPLIT 1 /* nrowgrid layout: force two clients to always split vertically */ +#include "functions.h" + + +static const Layout layouts[] = { + /* symbol arrange function */ + { "[]=", tile }, /* first entry is default */ + { "[M]", monocle }, + { "[@]", spiral }, + { "[\\]", dwindle }, + { "H[]", deck }, + { "TTT", bstack }, + { "===", bstackhoriz }, + { "HHH", grid }, + { "###", nrowgrid }, + { "---", horizgrid }, + { ":::", gaplessgrid }, + { "|M|", centeredmaster }, + { ">M>", centeredfloatingmaster }, + { "><>", NULL }, /* no layout function means floating behavior */ + { NULL, NULL }, +}; + +/* key definitions */ +#define MODKEY Mod1Mask +#define TAGKEYS(KEY,TAG) \ + { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ + { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, + +/* helper for spawning shell commands in the pre dwm-5.0 fashion */ +#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } + +/* commands */ + +static const Key keys[] = { + /* modifier key function argument */ + + // brightness and audio + {0, XF86XK_AudioLowerVolume, spawn, {.v = downvol}}, + {0, XF86XK_AudioMute, spawn, {.v = mutevol }}, + {0, XF86XK_AudioRaiseVolume, spawn, {.v = upvol}}, + {0, XF86XK_MonBrightnessUp, spawn, {.v = light_up}}, + {0, XF86XK_MonBrightnessDown, spawn, {.v = light_down}}, + + // screenshot fullscreen and cropped + {MODKEY|ControlMask, XK_u, spawn, + SHCMD("maim | xclip -selection clipboard -t image/png")}, + {MODKEY, XK_u, spawn, + SHCMD("maim --select | xclip -selection clipboard -t image/png")}, + + { MODKEY, XK_c, spawn, SHCMD("rofi -show drun") }, + { MODKEY, XK_Return, spawn, SHCMD("st")}, + + // toggle stuff + { MODKEY, XK_b, togglebar, {0} }, + { MODKEY|ControlMask, XK_t, togglegaps, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_f, togglefullscr, {0} }, + + { MODKEY|ControlMask, XK_w, tabmode, { -1 } }, + { MODKEY, XK_j, focusstack, {.i = +1 } }, + { MODKEY, XK_k, focusstack, {.i = -1 } }, + { MODKEY, XK_i, incnmaster, {.i = +1 } }, + { MODKEY, XK_d, incnmaster, {.i = -1 } }, + + // change m,cfact sizes + { MODKEY, XK_h, setmfact, {.f = -0.05} }, + { MODKEY, XK_l, setmfact, {.f = +0.05} }, + { MODKEY|ShiftMask, XK_h, setcfact, {.f = +0.25} }, + { MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} }, + { MODKEY|ShiftMask, XK_o, setcfact, {.f = 0.00} }, + + + { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } }, + { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } }, + { MODKEY|ShiftMask, XK_Return, zoom, {0} }, + { MODKEY, XK_Tab, view, {0} }, + + // overall gaps + { MODKEY|ControlMask, XK_i, incrgaps, {.i = +1 } }, + { MODKEY|ControlMask, XK_d, incrgaps, {.i = -1 } }, + + // inner gaps + { MODKEY|ShiftMask, XK_i, incrigaps, {.i = +1 } }, + { MODKEY|ControlMask|ShiftMask, XK_i, incrigaps, {.i = -1 } }, + + // outer gaps + { MODKEY|ControlMask, XK_o, incrogaps, {.i = +1 } }, + { MODKEY|ControlMask|ShiftMask, XK_o, incrogaps, {.i = -1 } }, + + // inner+outer hori, vert gaps + { MODKEY|ControlMask, XK_6, incrihgaps, {.i = +1 } }, + { MODKEY|ControlMask|ShiftMask, XK_6, incrihgaps, {.i = -1 } }, + { MODKEY|ControlMask, XK_7, incrivgaps, {.i = +1 } }, + { MODKEY|ControlMask|ShiftMask, XK_7, incrivgaps, {.i = -1 } }, + { MODKEY|ControlMask, XK_8, incrohgaps, {.i = +1 } }, + { MODKEY|ControlMask|ShiftMask, XK_8, incrohgaps, {.i = -1 } }, + { MODKEY|ControlMask, XK_9, incrovgaps, {.i = +1 } }, + { MODKEY|ControlMask|ShiftMask, XK_9, incrovgaps, {.i = -1 } }, + + { MODKEY|ControlMask|ShiftMask, XK_d, defaultgaps, {0} }, + + // layout + { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, + { MODKEY|ShiftMask, XK_f, setlayout, {.v = &layouts[1]} }, + { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, + { MODKEY|ControlMask, XK_g, setlayout, {.v = &layouts[10]} }, + { MODKEY|ControlMask|ShiftMask, XK_t, setlayout, {.v = &layouts[13]} }, + { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|ControlMask, XK_comma, cyclelayout, {.i = -1 } }, + { MODKEY|ControlMask, XK_period, cyclelayout, {.i = +1 } }, + { MODKEY, XK_0, view, {.ui = ~0 } }, + { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, + { MODKEY, XK_comma, focusmon, {.i = -1 } }, + { MODKEY, XK_period, focusmon, {.i = +1 } }, + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, + + // change border size + { MODKEY|ShiftMask, XK_minus, setborderpx, {.i = -1 } }, + { MODKEY|ShiftMask, XK_p, setborderpx, {.i = +1 } }, + { MODKEY|ShiftMask, XK_w, setborderpx, {.i = default_border } }, + + // kill dwm + { MODKEY|ControlMask, XK_q, spawn, SHCMD("killall bar.sh dwm") }, + + // kill window + { MODKEY, XK_q, killclient, {0} }, + + // restart + { MODKEY|ShiftMask, XK_r, restart, {0} }, + + // hide & restore windows + { MODKEY, XK_e, hidewin, {0} }, + { MODKEY|ShiftMask, XK_e, restorewin, {0} }, + + TAGKEYS( XK_1, 0) + TAGKEYS( XK_2, 1) + TAGKEYS( XK_3, 2) + TAGKEYS( XK_4, 3) + TAGKEYS( XK_5, 4) + TAGKEYS( XK_6, 5) + TAGKEYS( XK_7, 6) + TAGKEYS( XK_8, 7) + TAGKEYS( XK_9, 8) +}; + +/* button definitions */ +/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ +static const Button buttons[] = { + /* click event mask button function argument */ + { ClkLtSymbol, 0, Button1, setlayout, {0} }, + { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, + { ClkWinTitle, 0, Button2, zoom, {0} }, + { ClkStatusText, 0, Button2, spawn, SHCMD("st") }, + + /* Keep movemouse? */ + /* { ClkClientWin, MODKEY, Button1, movemouse, {0} }, */ + + /* placemouse options, choose which feels more natural: + * 0 - tiled position is relative to mouse cursor + * 1 - tiled position is relative to window center + * 2 - mouse pointer warps to window center + * + * The moveorplace uses movemouse or placemouse depending on the floating state + * of the selected client. Set up individual keybindings for the two if you want + * to control these separately (i.e. to retain the feature to move a tiled window + * into a floating position). + */ + { ClkClientWin, MODKEY, Button1, moveorplace, {.i = 0} }, + { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, + { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, + { ClkClientWin, ControlMask, Button1, dragmfact, {0} }, + { ClkClientWin, ControlMask, Button3, dragcfact, {0} }, + { ClkTagBar, 0, Button1, view, {0} }, + { ClkTagBar, 0, Button3, toggleview, {0} }, + { ClkTagBar, MODKEY, Button1, tag, {0} }, + { ClkTagBar, MODKEY, Button3, toggletag, {0} }, + { ClkTabBar, 0, Button1, focuswin, {0} }, + { ClkTabBar, 0, Button1, focuswin, {0} }, + { ClkTabPrev, 0, Button1, movestack, { .i = -1 } }, + { ClkTabNext, 0, Button1, movestack, { .i = +1 } }, + { ClkTabClose, 0, Button1, killclient, {0} }, +}; diff --git a/t480s/dwm/dwm/config.h b/t480s/dwm/dwm/config.h new file mode 100644 index 0000000..c50d2ae --- /dev/null +++ b/t480s/dwm/dwm/config.h @@ -0,0 +1,286 @@ +/* See LICENSE file for copyright and license details. */ + +#include + +/* appearance */ +static const unsigned int borderpx = 0; /* border pixel of windows */ +static const unsigned int default_border = 0; /* to switch back to default border after dynamic border resizing via keybinds */ +static const unsigned int snap = 32; /* snap pixel */ +static const unsigned int gappih = 10; /* horiz inner gap between windows */ +static const unsigned int gappiv = 10; /* vert inner gap between windows */ +static const unsigned int gappoh = 10; /* horiz outer gap between windows and screen edge */ +static const unsigned int gappov = 10; /* vert outer gap between windows and screen edge */ +static const int smartgaps = 0; /* 1 means no outer gap when there is only one window */ +static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */ +static const unsigned int systrayspacing = 2; /* systray spacing */ +static const int systraypinningfailfirst = 1; /* 1: if pinning fails,display systray on the 1st monitor,False: display systray on last monitor*/ +static const int showsystray = 1; /* 0 means no systray */ +static const int showbar = 1; /* 0 means no bar */ +static const int showtab = showtab_auto; +static const int toptab = 1; /* 0 means bottom tab */ +static const int floatbar = 1;/* 1 means the bar will float(don't have padding),0 means the bar have padding */ +static const int topbar = 1; /* 0 means bottom bar */ +static const int horizpadbar = 5; +static const int vertpadbar = 11; +static const int vertpadtab = 35; +static const int horizpadtabi = 15; +static const int horizpadtabo = 15; +static const int scalepreview = 4; +static const int tag_preview = 0; /* 1 means enable, 0 is off */ +static const int colorfultag = 1; /* 0 means use SchemeSel for selected non vacant tag */ +static const char *upvol[] = { "/usr/bin/pactl", "set-sink-volume", "0", "+5%", NULL }; +static const char *downvol[] = { "/usr/bin/pactl", "set-sink-volume", "0", "-5%", NULL }; +static const char *mutevol[] = { "/usr/bin/pactl", "set-sink-mute", "0", "toggle", NULL }; +static const char *light_up[] = {"/usr/bin/light", "-A", "5", NULL}; +static const char *light_down[] = {"/usr/bin/light", "-U", "5", NULL}; +static const int new_window_attach_on_end = 0; /* 1 means the new window will attach on the end; 0 means the new window will attach on the front,default is front */ +#define ICONSIZE 19 /* icon size */ +#define ICONSPACING 8 /* space between icon and title */ + +static const char *fonts[] = {"Noto Sans Mono:style:medium:size=12" ,"JetBrainsMono Nerd Font Mono:style:medium:size=19", + "Material Design Icons Desktop:size=11" }; + +// theme +#include "themes/gruvbox-dark.h" + +static const char *colors[][3] = { + /* fg bg border */ + [SchemeNorm] = { gray3, black, gray2 }, + [SchemeSel] = { gray4, blue, blue }, + [SchemeTitle] = { white, black, black }, // active window title + [TabSel] = { blue, gray2, black }, + [TabNorm] = { gray3, black, black }, + [SchemeTag] = { gray3, black, black }, + [SchemeTag1] = { blue, black, black }, + [SchemeTag2] = { red, black, black }, + [SchemeTag3] = { orange, black, black }, + [SchemeTag4] = { green, black, black }, + [SchemeTag5] = { pink, black, black }, + [SchemeLayout] = { green, black, black }, + [SchemeBtnPrev] = { green, black, black }, + [SchemeBtnNext] = { yellow, black, black }, + [SchemeBtnClose] = { red, black, black }, +}; + +/* tagging */ +static char *tags[] = {"", "", "", "", "", "", ""}; + +static const char* eww[] = { "eww", "open" , "eww", NULL }; + +static const Launcher launchers[] = { + /* command name to display */ + { eww, "" }, +}; + +static const int tagschemes[] = { + SchemeTag1, SchemeTag2, SchemeTag3, SchemeTag4, SchemeTag5 +}; + +static const unsigned int ulinepad = 5; /* horizontal padding between the underline and tag */ +static const unsigned int ulinestroke = 2; /* thickness / height of the underline */ +static const unsigned int ulinevoffset = 0; /* how far above the bottom of the bar the line should appear */ +static const int ulineall = 0; /* 1 to show underline on all tags, 0 for just the active ones */ + +static const Rule rules[] = { + /* xprop(1): + * WM_CLASS(STRING) = instance, class + * WM_NAME(STRING) = title + */ + /* class instance title tags mask iscentered isfloating monitor */ + { "Gimp", NULL, NULL, 0, 0, 1, -1 }, + { "Firefox", NULL, NULL, 1 << 8, 0, 0, -1 }, + { "eww", NULL, NULL, 0, 0, 1, -1 }, +}; + +/* layout(s) */ +static const float mfact = 0.50; /* factor of master area size [0.05..0.95] */ +static const int nmaster = 1; /* number of clients in master area */ +static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */ +static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ + +#define FORCE_VSPLIT 1 /* nrowgrid layout: force two clients to always split vertically */ +#include "functions.h" + + +static const Layout layouts[] = { + /* symbol arrange function */ + { "[]=", tile }, /* first entry is default */ + { "[M]", monocle }, + { "[@]", spiral }, + { "[\\]", dwindle }, + { "H[]", deck }, + { "TTT", bstack }, + { "===", bstackhoriz }, + { "HHH", grid }, + { "###", nrowgrid }, + { "---", horizgrid }, + { ":::", gaplessgrid }, + { "|M|", centeredmaster }, + { ">M>", centeredfloatingmaster }, + { "><>", NULL }, /* no layout function means floating behavior */ + { NULL, NULL }, +}; + +/* key definitions */ +#define MODKEY Mod1Mask +#define TAGKEYS(KEY,TAG) \ + { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ + { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, + +/* helper for spawning shell commands in the pre dwm-5.0 fashion */ +#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } + +/* commands */ + +static const Key keys[] = { + /* modifier key function argument */ + + // brightness and audio + {0, XF86XK_AudioLowerVolume, spawn, {.v = downvol}}, + {0, XF86XK_AudioMute, spawn, {.v = mutevol }}, + {0, XF86XK_AudioRaiseVolume, spawn, {.v = upvol}}, + {0, XF86XK_MonBrightnessUp, spawn, {.v = light_up}}, + {0, XF86XK_MonBrightnessDown, spawn, {.v = light_down}}, + + // screenshot fullscreen and cropped + {MODKEY|ControlMask, XK_u, spawn, + SHCMD("maim | xclip -selection clipboard -t image/png")}, + {MODKEY, XK_u, spawn, + SHCMD("maim --select | xclip -selection clipboard -t image/png")}, + + { MODKEY, XK_c, spawn, SHCMD("rofi -show drun") }, + { MODKEY, XK_Return, spawn, SHCMD("st")}, + + // toggle stuff + { MODKEY, XK_b, togglebar, {0} }, + { MODKEY|ControlMask, XK_t, togglegaps, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_f, togglefullscr, {0} }, + + { MODKEY|ControlMask, XK_w, tabmode, { -1 } }, + { MODKEY, XK_j, focusstack, {.i = +1 } }, + { MODKEY, XK_k, focusstack, {.i = -1 } }, + { MODKEY, XK_i, incnmaster, {.i = +1 } }, + { MODKEY, XK_d, incnmaster, {.i = -1 } }, + + // change m,cfact sizes + { MODKEY, XK_h, setmfact, {.f = -0.05} }, + { MODKEY, XK_l, setmfact, {.f = +0.05} }, + { MODKEY|ShiftMask, XK_h, setcfact, {.f = +0.25} }, + { MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} }, + { MODKEY|ShiftMask, XK_o, setcfact, {.f = 0.00} }, + + + { MODKEY|ShiftMask, XK_j, movestack, {.i = +1 } }, + { MODKEY|ShiftMask, XK_k, movestack, {.i = -1 } }, + { MODKEY|ShiftMask, XK_Return, zoom, {0} }, + { MODKEY, XK_Tab, view, {0} }, + + // overall gaps + { MODKEY|ControlMask, XK_i, incrgaps, {.i = +1 } }, + { MODKEY|ControlMask, XK_d, incrgaps, {.i = -1 } }, + + // inner gaps + { MODKEY|ShiftMask, XK_i, incrigaps, {.i = +1 } }, + { MODKEY|ControlMask|ShiftMask, XK_i, incrigaps, {.i = -1 } }, + + // outer gaps + { MODKEY|ControlMask, XK_o, incrogaps, {.i = +1 } }, + { MODKEY|ControlMask|ShiftMask, XK_o, incrogaps, {.i = -1 } }, + + // inner+outer hori, vert gaps + { MODKEY|ControlMask, XK_6, incrihgaps, {.i = +1 } }, + { MODKEY|ControlMask|ShiftMask, XK_6, incrihgaps, {.i = -1 } }, + { MODKEY|ControlMask, XK_7, incrivgaps, {.i = +1 } }, + { MODKEY|ControlMask|ShiftMask, XK_7, incrivgaps, {.i = -1 } }, + { MODKEY|ControlMask, XK_8, incrohgaps, {.i = +1 } }, + { MODKEY|ControlMask|ShiftMask, XK_8, incrohgaps, {.i = -1 } }, + { MODKEY|ControlMask, XK_9, incrovgaps, {.i = +1 } }, + { MODKEY|ControlMask|ShiftMask, XK_9, incrovgaps, {.i = -1 } }, + + { MODKEY|ControlMask|ShiftMask, XK_d, defaultgaps, {0} }, + + // layout + { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, + { MODKEY|ShiftMask, XK_f, setlayout, {.v = &layouts[1]} }, + { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, + { MODKEY|ControlMask, XK_g, setlayout, {.v = &layouts[10]} }, + { MODKEY|ControlMask|ShiftMask, XK_t, setlayout, {.v = &layouts[13]} }, + { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|ControlMask, XK_comma, cyclelayout, {.i = -1 } }, + { MODKEY|ControlMask, XK_period, cyclelayout, {.i = +1 } }, + { MODKEY, XK_0, view, {.ui = ~0 } }, + { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, + { MODKEY, XK_comma, focusmon, {.i = -1 } }, + { MODKEY, XK_period, focusmon, {.i = +1 } }, + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, + + // change border size + { MODKEY|ShiftMask, XK_minus, setborderpx, {.i = -1 } }, + { MODKEY|ShiftMask, XK_p, setborderpx, {.i = +1 } }, + { MODKEY|ShiftMask, XK_w, setborderpx, {.i = default_border } }, + + // kill dwm + { MODKEY|ControlMask, XK_q, spawn, SHCMD("killall bar.sh dwm") }, + + // kill window + { MODKEY, XK_q, killclient, {0} }, + + // restart + { MODKEY|ShiftMask, XK_r, restart, {0} }, + + // hide & restore windows + { MODKEY, XK_e, hidewin, {0} }, + { MODKEY|ShiftMask, XK_e, restorewin, {0} }, + + TAGKEYS( XK_1, 0) + TAGKEYS( XK_2, 1) + TAGKEYS( XK_3, 2) + TAGKEYS( XK_4, 3) + TAGKEYS( XK_5, 4) + TAGKEYS( XK_6, 5) + TAGKEYS( XK_7, 6) + TAGKEYS( XK_8, 7) + TAGKEYS( XK_9, 8) +}; + +/* button definitions */ +/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ +static const Button buttons[] = { + /* click event mask button function argument */ + { ClkLtSymbol, 0, Button1, setlayout, {0} }, + { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, + { ClkWinTitle, 0, Button2, zoom, {0} }, + { ClkStatusText, 0, Button2, spawn, SHCMD("st") }, + + /* Keep movemouse? */ + /* { ClkClientWin, MODKEY, Button1, movemouse, {0} }, */ + + /* placemouse options, choose which feels more natural: + * 0 - tiled position is relative to mouse cursor + * 1 - tiled position is relative to window center + * 2 - mouse pointer warps to window center + * + * The moveorplace uses movemouse or placemouse depending on the floating state + * of the selected client. Set up individual keybindings for the two if you want + * to control these separately (i.e. to retain the feature to move a tiled window + * into a floating position). + */ + { ClkClientWin, MODKEY, Button1, moveorplace, {.i = 0} }, + { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, + { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, + { ClkClientWin, ControlMask, Button1, dragmfact, {0} }, + { ClkClientWin, ControlMask, Button3, dragcfact, {0} }, + { ClkTagBar, 0, Button1, view, {0} }, + { ClkTagBar, 0, Button3, toggleview, {0} }, + { ClkTagBar, MODKEY, Button1, tag, {0} }, + { ClkTagBar, MODKEY, Button3, toggletag, {0} }, + { ClkTabBar, 0, Button1, focuswin, {0} }, + { ClkTabBar, 0, Button1, focuswin, {0} }, + { ClkTabPrev, 0, Button1, movestack, { .i = -1 } }, + { ClkTabNext, 0, Button1, movestack, { .i = +1 } }, + { ClkTabClose, 0, Button1, killclient, {0} }, +}; diff --git a/t480s/dwm/dwm/config.mk b/t480s/dwm/dwm/config.mk new file mode 100644 index 0000000..18af518 --- /dev/null +++ b/t480s/dwm/dwm/config.mk @@ -0,0 +1,39 @@ +# dwm version +VERSION = 6.4 + +# Customize below to fit your system + +# paths +PREFIX = /usr/local +MANPREFIX = ${PREFIX}/share/man + +X11INC = /usr/X11R6/include +X11LIB = /usr/X11R6/lib + +# Xinerama, comment if you don't want it +XINERAMALIBS = -lXinerama +XINERAMAFLAGS = -DXINERAMA + +# freetype +FREETYPELIBS = -lfontconfig -lXft +FREETYPEINC = /usr/include/freetype2 +# OpenBSD (uncomment) +#FREETYPEINC = ${X11INC}/freetype2 +#MANPREFIX = ${PREFIX}/man + +# includes and libs +INCS = -I${X11INC} -I${FREETYPEINC} +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXrender -lImlib2 + +# flags +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} +CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -O3 -march=native ${INCS} ${CPPFLAGS} +LDFLAGS = ${LIBS} + +# Solaris +#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" +#LDFLAGS = ${LIBS} + +# compiler and linker +CC = cc diff --git a/t480s/dwm/dwm/drw.c b/t480s/dwm/dwm/drw.c new file mode 100644 index 0000000..ff26025 --- /dev/null +++ b/t480s/dwm/dwm/drw.c @@ -0,0 +1,527 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include +#include + +#include "drw.h" +#include "util.h" + +#define UTF_INVALID 0xFFFD +#define UTF_SIZ 4 + +static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; +static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; +static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; +static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; + +static long +utf8decodebyte(const char c, size_t *i) +{ + for (*i = 0; *i < (UTF_SIZ + 1); ++(*i)) + if (((unsigned char)c & utfmask[*i]) == utfbyte[*i]) + return (unsigned char)c & ~utfmask[*i]; + return 0; +} + +static size_t +utf8validate(long *u, size_t i) +{ + if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF)) + *u = UTF_INVALID; + for (i = 1; *u > utfmax[i]; ++i) + ; + return i; +} + +static size_t +utf8decode(const char *c, long *u, size_t clen) +{ + size_t i, j, len, type; + long udecoded; + + *u = UTF_INVALID; + if (!clen) + return 0; + udecoded = utf8decodebyte(c[0], &len); + if (!BETWEEN(len, 1, UTF_SIZ)) + return 1; + for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { + udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type); + if (type) + return j; + } + if (j < len) + return 0; + *u = udecoded; + utf8validate(u, len); + + return len; +} + +Drw * +drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h) +{ + Drw *drw = ecalloc(1, sizeof(Drw)); + + drw->dpy = dpy; + drw->screen = screen; + drw->root = root; + drw->w = w; + drw->h = h; + drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen)); + drw->picture = XRenderCreatePicture(dpy, drw->drawable, XRenderFindVisualFormat(dpy, DefaultVisual(dpy, screen)), 0, NULL); + drw->gc = XCreateGC(dpy, root, 0, NULL); + XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter); + + return drw; +} + +void +drw_resize(Drw *drw, unsigned int w, unsigned int h) +{ + if (!drw) + return; + + drw->w = w; + drw->h = h; + if (drw->picture) + XRenderFreePicture(drw->dpy, drw->picture); + if (drw->drawable) + XFreePixmap(drw->dpy, drw->drawable); + drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); + drw->picture = XRenderCreatePicture(drw->dpy, drw->drawable, XRenderFindVisualFormat(drw->dpy, DefaultVisual(drw->dpy, drw->screen)), 0, NULL); +} + +void +drw_free(Drw *drw) +{ + XRenderFreePicture(drw->dpy, drw->picture); + XFreePixmap(drw->dpy, drw->drawable); + XFreeGC(drw->dpy, drw->gc); + drw_fontset_free(drw->fonts); + free(drw); +} + +/* This function is an implementation detail. Library users should use + * drw_fontset_create instead. + */ +static Fnt * +xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) +{ + Fnt *font; + XftFont *xfont = NULL; + FcPattern *pattern = NULL; + + if (fontname) { + /* Using the pattern found at font->xfont->pattern does not yield the + * same substitution results as using the pattern returned by + * FcNameParse; using the latter results in the desired fallback + * behaviour whereas the former just results in missing-character + * rectangles being drawn, at least with some fonts. */ + if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { + fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname); + return NULL; + } + if (!(pattern = FcNameParse((FcChar8 *) fontname))) { + fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname); + XftFontClose(drw->dpy, xfont); + return NULL; + } + } else if (fontpattern) { + if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { + fprintf(stderr, "error, cannot load font from pattern.\n"); + return NULL; + } + } else { + die("no font specified."); + } + + font = ecalloc(1, sizeof(Fnt)); + font->xfont = xfont; + font->pattern = pattern; + font->h = xfont->ascent + xfont->descent; + font->dpy = drw->dpy; + + return font; +} + +static void +xfont_free(Fnt *font) +{ + if (!font) + return; + if (font->pattern) + FcPatternDestroy(font->pattern); + XftFontClose(font->dpy, font->xfont); + free(font); +} + +Fnt* +drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) +{ + Fnt *cur, *ret = NULL; + size_t i; + + if (!drw || !fonts) + return NULL; + + for (i = 1; i <= fontcount; i++) { + if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) { + cur->next = ret; + ret = cur; + } + } + return (drw->fonts = ret); +} + +void +drw_fontset_free(Fnt *font) +{ + if (font) { + drw_fontset_free(font->next); + xfont_free(font); + } +} + +void +drw_clr_create(Drw *drw, Clr *dest, const char *clrname) +{ + if (!drw || !dest || !clrname) + return; + + if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), + DefaultColormap(drw->dpy, drw->screen), + clrname, dest)) + die("error, cannot allocate color '%s'", clrname); + + dest->pixel |= 0xff << 24; +} + +/* Wrapper to create color schemes. The caller has to call free(3) on the + * returned color scheme when done using it. */ +Clr * +drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) +{ + size_t i; + Clr *ret; + + /* need at least two colors for a scheme */ + if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor)))) + return NULL; + + for (i = 0; i < clrcount; i++) + drw_clr_create(drw, &ret[i], clrnames[i]); + return ret; +} + +void +drw_setfontset(Drw *drw, Fnt *set) +{ + if (drw) + drw->fonts = set; +} + +void +drw_setscheme(Drw *drw, Clr *scm) +{ + if (drw) + drw->scheme = scm; +} + +Picture +drw_picture_create_resized(Drw *drw, char *src, unsigned int srcw, unsigned int srch, unsigned int dstw, unsigned int dsth) { + Pixmap pm; + Picture pic; + GC gc; + + if (srcw <= (dstw << 1u) && srch <= (dsth << 1u)) { + XImage img = { + srcw, srch, 0, ZPixmap, src, + ImageByteOrder(drw->dpy), BitmapUnit(drw->dpy), BitmapBitOrder(drw->dpy), 32, + 32, 0, 32, + 0, 0, 0 + }; + XInitImage(&img); + + pm = XCreatePixmap(drw->dpy, drw->root, srcw, srch, 32); + gc = XCreateGC(drw->dpy, pm, 0, NULL); + XPutImage(drw->dpy, pm, gc, &img, 0, 0, 0, 0, srcw, srch); + XFreeGC(drw->dpy, gc); + + pic = XRenderCreatePicture(drw->dpy, pm, XRenderFindStandardFormat(drw->dpy, PictStandardARGB32), 0, NULL); + XFreePixmap(drw->dpy, pm); + + XRenderSetPictureFilter(drw->dpy, pic, FilterBilinear, NULL, 0); + XTransform xf; + xf.matrix[0][0] = (srcw << 16u) / dstw; xf.matrix[0][1] = 0; xf.matrix[0][2] = 0; + xf.matrix[1][0] = 0; xf.matrix[1][1] = (srch << 16u) / dsth; xf.matrix[1][2] = 0; + xf.matrix[2][0] = 0; xf.matrix[2][1] = 0; xf.matrix[2][2] = 65536; + XRenderSetPictureTransform(drw->dpy, pic, &xf); + } else { + Imlib_Image origin = imlib_create_image_using_data(srcw, srch, (DATA32 *)src); + if (!origin) return None; + imlib_context_set_image(origin); + imlib_image_set_has_alpha(1); + Imlib_Image scaled = imlib_create_cropped_scaled_image(0, 0, srcw, srch, dstw, dsth); + imlib_free_image_and_decache(); + if (!scaled) return None; + imlib_context_set_image(scaled); + imlib_image_set_has_alpha(1); + + XImage img = { + dstw, dsth, 0, ZPixmap, (char *)imlib_image_get_data_for_reading_only(), + ImageByteOrder(drw->dpy), BitmapUnit(drw->dpy), BitmapBitOrder(drw->dpy), 32, + 32, 0, 32, + 0, 0, 0 + }; + XInitImage(&img); + + pm = XCreatePixmap(drw->dpy, drw->root, dstw, dsth, 32); + gc = XCreateGC(drw->dpy, pm, 0, NULL); + XPutImage(drw->dpy, pm, gc, &img, 0, 0, 0, 0, dstw, dsth); + imlib_free_image_and_decache(); + XFreeGC(drw->dpy, gc); + + pic = XRenderCreatePicture(drw->dpy, pm, XRenderFindStandardFormat(drw->dpy, PictStandardARGB32), 0, NULL); + XFreePixmap(drw->dpy, pm); + } + + return pic; +} + +void +drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert) +{ + if (!drw || !drw->scheme) + return; + XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel); + if (filled) + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); + else + XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1); +} + +int +drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert) +{ + int i, ty, ellipsis_x = 0; + unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len; + XftDraw *d = NULL; + Fnt *usedfont, *curfont, *nextfont; + int utf8strlen, utf8charlen, render = x || y || w || h; + long utf8codepoint = 0; + const char *utf8str; + FcCharSet *fccharset; + FcPattern *fcpattern; + FcPattern *match; + XftResult result; + int charexists = 0, overflow = 0; + /* keep track of a couple codepoints for which we have no match. */ + enum { nomatches_len = 64 }; + static struct { long codepoint[nomatches_len]; unsigned int idx; } nomatches; + static unsigned int ellipsis_width = 0; + + if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts) + return 0; + + if (!render) { + w = invert ? invert : ~invert; + } else { + XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); + XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); + d = XftDrawCreate(drw->dpy, drw->drawable, + DefaultVisual(drw->dpy, drw->screen), + DefaultColormap(drw->dpy, drw->screen)); + x += lpad; + w -= lpad; + } + + usedfont = drw->fonts; + if (!ellipsis_width && render) + ellipsis_width = drw_fontset_getwidth(drw, "..."); + while (1) { + ew = ellipsis_len = utf8strlen = 0; + utf8str = text; + nextfont = NULL; + while (*text) { + utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ); + for (curfont = drw->fonts; curfont; curfont = curfont->next) { + charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); + if (charexists) { + drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL); + if (ew + ellipsis_width <= w) { + /* keep track where the ellipsis still fits */ + ellipsis_x = x + ew; + ellipsis_w = w - ew; + ellipsis_len = utf8strlen; + } + + if (ew + tmpw > w) { + overflow = 1; + /* called from drw_fontset_getwidth_clamp(): + * it wants the width AFTER the overflow + */ + if (!render) + x += tmpw; + else + utf8strlen = ellipsis_len; + } else if (curfont == usedfont) { + utf8strlen += utf8charlen; + text += utf8charlen; + ew += tmpw; + } else { + nextfont = curfont; + } + break; + } + } + + if (overflow || !charexists || nextfont) + break; + else + charexists = 0; + } + + if (utf8strlen) { + if (render) { + ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; + XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], + usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen); + } + x += ew; + w -= ew; + } + if (render && overflow) + drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert); + + if (!*text || overflow) { + break; + } else if (nextfont) { + charexists = 0; + usedfont = nextfont; + } else { + /* Regardless of whether or not a fallback font is found, the + * character must be drawn. */ + charexists = 1; + + for (i = 0; i < nomatches_len; ++i) { + /* avoid calling XftFontMatch if we know we won't find a match */ + if (utf8codepoint == nomatches.codepoint[i]) + goto no_match; + } + + fccharset = FcCharSetCreate(); + FcCharSetAddChar(fccharset, utf8codepoint); + + if (!drw->fonts->pattern) { + /* Refer to the comment in xfont_create for more information. */ + die("the first font in the cache must be loaded from a font string."); + } + + fcpattern = FcPatternDuplicate(drw->fonts->pattern); + FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); + FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); + + FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); + FcDefaultSubstitute(fcpattern); + match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result); + + FcCharSetDestroy(fccharset); + FcPatternDestroy(fcpattern); + + if (match) { + usedfont = xfont_create(drw, NULL, match); + if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) { + for (curfont = drw->fonts; curfont->next; curfont = curfont->next) + ; /* NOP */ + curfont->next = usedfont; + } else { + xfont_free(usedfont); + nomatches.codepoint[++nomatches.idx % nomatches_len] = utf8codepoint; +no_match: + usedfont = drw->fonts; + } + } + } + } + if (d) + XftDrawDestroy(d); + + return x + (render ? w : 0); +} + +void +drw_pic(Drw *drw, int x, int y, unsigned int w, unsigned int h, Picture pic) +{ + if (!drw) + return; + XRenderComposite(drw->dpy, PictOpOver, pic, None, drw->picture, 0, 0, 0, 0, x, y, w, h); +} + +void +drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) +{ + if (!drw) + return; + + XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); + XSync(drw->dpy, False); +} + +unsigned int +drw_fontset_getwidth(Drw *drw, const char *text) +{ + if (!drw || !drw->fonts || !text) + return 0; + return drw_text(drw, 0, 0, 0, 0, 0, text, 0); +} + +unsigned int +drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n) +{ + unsigned int tmp = 0; + if (drw && drw->fonts && text && n) + tmp = drw_text(drw, 0, 0, 0, 0, 0, text, n); + return MIN(n, tmp); +} + +void +drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h) +{ + XGlyphInfo ext; + + if (!font || !text) + return; + + XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext); + if (w) + *w = ext.xOff; + if (h) + *h = font->h; +} + +Cur * +drw_cur_create(Drw *drw, int shape) +{ + Cur *cur; + + if (!drw || !(cur = ecalloc(1, sizeof(Cur)))) + return NULL; + + cur->cursor = XCreateFontCursor(drw->dpy, shape); + + return cur; +} + +void +drw_cur_free(Drw *drw, Cur *cursor) +{ + if (!cursor) + return; + + XFreeCursor(drw->dpy, cursor->cursor); + free(cursor); +} diff --git a/t480s/dwm/dwm/drw.h b/t480s/dwm/dwm/drw.h new file mode 100644 index 0000000..1288d66 --- /dev/null +++ b/t480s/dwm/dwm/drw.h @@ -0,0 +1,63 @@ +/* See LICENSE file for copyright and license details. */ + +typedef struct { + Cursor cursor; +} Cur; + +typedef struct Fnt { + Display *dpy; + unsigned int h; + XftFont *xfont; + FcPattern *pattern; + struct Fnt *next; +} Fnt; + +enum { ColFg, ColBg, ColBorder }; /* Clr scheme index */ +typedef XftColor Clr; + +typedef struct { + unsigned int w, h; + Display *dpy; + int screen; + Window root; + Drawable drawable; + Picture picture; + Pixmap bgmap; + GC gc; + Clr *scheme; + Fnt *fonts; +} Drw; + +/* Drawable abstraction */ +Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); +void drw_resize(Drw *drw, unsigned int w, unsigned int h); +void drw_free(Drw *drw); + +/* Fnt abstraction */ +Fnt *drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount); +void drw_fontset_free(Fnt* set); +unsigned int drw_fontset_getwidth(Drw *drw, const char *text); +unsigned int drw_fontset_getwidth_clamp(Drw *drw, const char *text, unsigned int n); +void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h); + +/* Colorscheme abstraction */ +void drw_clr_create(Drw *drw, Clr *dest, const char *clrname); +Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount); + +/* Cursor abstraction */ +Cur *drw_cur_create(Drw *drw, int shape); +void drw_cur_free(Drw *drw, Cur *cursor); + +/* Drawing context manipulation */ +void drw_setfontset(Drw *drw, Fnt *set); +void drw_setscheme(Drw *drw, Clr *scm); + +Picture drw_picture_create_resized(Drw *drw, char *src, unsigned int src_w, unsigned int src_h, unsigned int dst_w, unsigned int dst_h); + +/* Drawing functions */ +void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert); +int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert); +void drw_pic(Drw *drw, int x, int y, unsigned int w, unsigned int h, Picture pic); + +/* Map functions */ +void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); diff --git a/t480s/dwm/dwm/drw.o b/t480s/dwm/dwm/drw.o new file mode 100644 index 0000000000000000000000000000000000000000..492ba520adcacdafdf3d14856a3adb87aae0190a GIT binary patch literal 15968 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 literal 0 HcmV?d00001 diff --git a/t480s/dwm/dwm/dwm b/t480s/dwm/dwm/dwm new file mode 100755 index 0000000000000000000000000000000000000000..dfe735bf2120e8992be63d2ca992a38331d6954b GIT binary patch literal 136672 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%0D6W{frP}e80Y_lo)`e#Lue!+6@B^7 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 literal 0 HcmV?d00001 diff --git a/t480s/dwm/dwm/dwm.1 b/t480s/dwm/dwm/dwm.1 new file mode 100644 index 0000000..5db4c82 --- /dev/null +++ b/t480s/dwm/dwm/dwm.1 @@ -0,0 +1,179 @@ +.TH DWM 1 dwm\-VERSION +.SH NAME +dwm \- dynamic window manager +.SH SYNOPSIS +.B dwm +.RB [ \-v ] +.SH DESCRIPTION +dwm is a dynamic window manager for X. It manages windows in tiled, monocle +and floating layouts. Either layout can be applied dynamically, optimising the +environment for the application in use and the task performed. +.P +In tiled layouts windows are managed in a master and stacking area. The master +area on the left contains one window by default, and the stacking area on the +right contains all other windows. The number of master area windows can be +adjusted from zero to an arbitrary number. In monocle layout all windows are +maximised to the screen size. In floating layout windows can be resized and +moved freely. Dialog windows are always managed floating, regardless of the +layout applied. +.P +Windows are grouped by tags. Each window can be tagged with one or multiple +tags. Selecting certain tags displays all windows with these tags. +.P +Each screen contains a small status bar which displays all available tags, the +layout, the title of the focused window, and the text read from the root window +name property, if the screen is focused. A floating window is indicated with an +empty square and a maximised floating window is indicated with a filled square +before the windows title. The selected tags are indicated with a different +color. The tags of the focused window are indicated with a filled square in the +top left corner. The tags which are applied to one or more windows are +indicated with an empty square in the top left corner. +.P +dwm draws a small border around windows to indicate the focus state. +.SH OPTIONS +.TP +.B \-v +prints version information to stderr, then exits. +.SH USAGE +.SS Status bar +.TP +.B X root window name +is read and displayed in the status text area. It can be set with the +.BR xsetroot (1) +command. +.TP +.B Button1 +click on a tag label to display all windows with that tag, click on the layout +label toggles between tiled and floating layout. +.TP +.B Button3 +click on a tag label adds/removes all windows with that tag to/from the view. +.TP +.B Mod1\-Button1 +click on a tag label applies that tag to the focused window. +.TP +.B Mod1\-Button3 +click on a tag label adds/removes that tag to/from the focused window. +.SS Keyboard commands +.TP +.B Mod1\-Shift\-Return +Start +.BR st(1). +.TP +.B Mod1\-p +Spawn +.TP +.B Mod1\-, +Focus previous screen, if any. +.TP +.B Mod1\-. +Focus next screen, if any. +.TP +.B Mod1\-Shift\-, +Send focused window to previous screen, if any. +.TP +.B Mod1\-Shift\-. +Send focused window to next screen, if any. +.TP +.B Mod1\-b +Toggles bar on and off. +.TP +.B Mod1\-t +Sets tiled layout. +.TP +.B Mod1\-f +Sets floating layout. +.TP +.B Mod1\-m +Sets monocle layout. +.TP +.B Mod1\-space +Toggles between current and previous layout. +.TP +.B Mod1\-Control\-, +Cycles backwards in layout list. +.TP +.B Mod1\-Control\-. +Cycles forwards in layout list. +.TP +.B Mod1\-j +Focus next window. +.TP +.B Mod1\-k +Focus previous window. +.TP +.B Mod1\-i +Increase number of windows in master area. +.TP +.B Mod1\-d +Decrease number of windows in master area. +.TP +.B Mod1\-l +Increase master area size. +.TP +.B Mod1\-h +Decrease master area size. +.TP +.B Mod1\-Return +Zooms/cycles focused window to/from master area (tiled layouts only). +.TP +.B Mod1\-Shift\-c +Close focused window. +.TP +.B Mod1\-Shift\-space +Toggle focused window between tiled and floating state. +.TP +.B Mod1\-Tab +Toggles to the previously selected tags. +.TP +.B Mod1\-Shift\-[1..n] +Apply nth tag to focused window. +.TP +.B Mod1\-Shift\-0 +Apply all tags to focused window. +.TP +.B Mod1\-Control\-Shift\-[1..n] +Add/remove nth tag to/from focused window. +.TP +.B Mod1\-[1..n] +View all windows with nth tag. +.TP +.B Mod1\-0 +View all windows with any tag. +.TP +.B Mod1\-Control\-[1..n] +Add/remove all windows with nth tag to/from the view. +.TP +.B Mod1\-Shift\-q +Restart dwm. +.SS Mouse commands +.TP +.B Mod1\-Button1 +Move focused window while dragging. Tiled windows will be toggled to the floating state. +.TP +.B Mod1\-Button2 +Toggles focused window between floating and tiled state. +.TP +.B Mod1\-Button3 +Resize focused window while dragging. Tiled windows will be toggled to the floating state. +.SH CUSTOMIZATION +dwm is customized by creating a custom config.h and (re)compiling the source +code. This keeps it fast, secure and simple. +.SH SEE ALSO +.BR st (1) +.SH ISSUES +Java applications which use the XToolkit/XAWT backend may draw grey windows +only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early +JDK 1.6 versions, because it assumes a reparenting window manager. Possible workarounds +are using JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or setting the +environment variable +.BR AWT_TOOLKIT=MToolkit +(to use the older Motif backend instead) or running +.B xprop -root -f _NET_WM_NAME 32a -set _NET_WM_NAME LG3D +or +.B wmname LG3D +(to pretend that a non-reparenting window manager is running that the +XToolkit/XAWT backend can recognize) or when using OpenJDK setting the environment variable +.BR _JAVA_AWT_WM_NONREPARENTING=1 . +.SH BUGS +Send all bug reports with a patch to hackers@suckless.org. diff --git a/t480s/dwm/dwm/dwm.c b/t480s/dwm/dwm/dwm.c new file mode 100644 index 0000000..402bc1c --- /dev/null +++ b/t480s/dwm/dwm/dwm.c @@ -0,0 +1,3844 @@ +/* See LICENSE file for copyright and license details. + * + * dynamic window manager is designed like any other X client as well. It is + * driven through handling X events. In contrast to other X clients, a window + * manager selects for SubstructureRedirectMask on the root window, to receive + * events about window (dis-)appearance. Only one X connection at a time is + * allowed to select for this event mask. + * + * The event handlers of dwm are organized in an array which is accessed + * whenever a new event has been fetched. This allows event dispatching + * in O(1) time. + * + * Each child of the root window is called a client, except windows which have + * set the override_redirect flag. Clients are organized in a linked client + * list on each monitor, the focus history is remembered through a stack list + * on each monitor. Each client contains a bit array to indicate the tags of a + * client. + * + * Keys and tagging rules are organized as arrays and defined in config.h. + * + * To understand everything else, start reading main(). + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef XINERAMA +#include +#endif /* XINERAMA */ +#include +#include +#include "drw.h" +#include "util.h" + +/* macros */ +#define BUTTONMASK (ButtonPressMask | ButtonReleaseMask) +#define CLEANMASK(mask) \ + (mask & ~(numlockmask | LockMask) & \ + (ShiftMask | ControlMask | Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | \ + Mod5Mask)) +#define INTERSECT(x, y, w, h, m) \ + (MAX(0, MIN((x) + (w), (m)->wx + (m)->ww) - MAX((x), (m)->wx)) * \ + MAX(0, MIN((y) + (h), (m)->wy + (m)->wh) - MAX((y), (m)->wy))) +#define INTERSECTC(x,y,w,h,z) (MAX(0, MIN((x)+(w),(z)->x+(z)->w) - MAX((x),(z)->x)) \ + * MAX(0, MIN((y)+(h),(z)->y+(z)->h) - MAX((y),(z)->y))) +#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) +#define HIDDEN(C) ((getstate(C->win) == IconicState)) +#define LENGTH(X) (sizeof X / sizeof X[0]) +#define MOUSEMASK (BUTTONMASK | PointerMotionMask) +#define WIDTH(X) ((X)->w + 2 * (X)->bw) +#define HEIGHT(X) ((X)->h + 2 * (X)->bw) +#define TAGMASK ((1 << LENGTH(tags)) - 1) +#define TAGSLENGTH (LENGTH(tags)) +#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) +#define MAXTABS 50 + +#define SYSTEM_TRAY_REQUEST_DOCK 0 + +/* XEMBED messages */ +#define XEMBED_EMBEDDED_NOTIFY 0 +#define XEMBED_WINDOW_ACTIVATE 1 +#define XEMBED_FOCUS_IN 4 +#define XEMBED_MODALITY_ON 10 + +#define XEMBED_MAPPED (1 << 0) +#define XEMBED_WINDOW_ACTIVATE 1 +#define XEMBED_WINDOW_DEACTIVATE 2 + +#define VERSION_MAJOR 0 +#define VERSION_MINOR 0 +#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR + +/* enums */ +enum { + CurNormal, + CurResize, + CurMove, + CurResizeHorzArrow, + CurResizeVertArrow, + CurLast +}; /* cursor */ +enum { + SchemeNorm, + SchemeSel, + SchemeTitle, + SchemeTag, + SchemeTag1, + SchemeTag2, + SchemeTag3, + SchemeTag4, + SchemeTag5, + SchemeLayout, + TabSel, + TabNorm, + SchemeBtnPrev, + SchemeBtnNext, + SchemeBtnClose +}; /* color schemes */ +enum { + NetSupported, + NetWMName, + NetWMIcon, + NetWMState, + NetWMCheck, + NetSystemTray, + NetSystemTrayOP, + NetSystemTrayOrientation, + NetSystemTrayOrientationHorz, + NetWMFullscreen, + NetActiveWindow, + NetWMWindowType, + NetWMWindowTypeDialog, + NetClientList, + NetClientInfo, + NetDesktopNames, + NetDesktopViewport, + NetNumberOfDesktops, + NetCurrentDesktop, + NetLast +}; /* EWMH atoms */ +enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */ +enum { + WMProtocols, + WMDelete, + WMState, + WMTakeFocus, + WMLast +}; /* default atoms */ +enum { + ClkTagBar, + ClkTabBar, + ClkTabPrev, + ClkTabNext, + ClkTabClose, + ClkLtSymbol, + ClkStatusText, + ClkWinTitle, + ClkClientWin, + ClkRootWin, + ClkLast +}; /* clicks */ + +enum showtab_modes { + showtab_never, + showtab_auto, + showtab_nmodes, + showtab_always +}; /* tab modes */ + +typedef union { + int i; + unsigned int ui; + float f; + const void *v; +} Arg; + +typedef struct { + unsigned int click; + unsigned int mask; + unsigned int button; + void (*func)(const Arg *arg); + const Arg arg; +} Button; + +typedef struct Monitor Monitor; +typedef struct Client Client; +struct Client { + char name[256]; + float mina, maxa; + float cfact; + int x, y, w, h; + int oldx, oldy, oldw, oldh; + int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid; + int bw, oldbw; + unsigned int tags; + int isfixed, iscentered, isfloating, isurgent, neverfocus, oldstate, isfullscreen; + unsigned int icw, ich; Picture icon; + int beingmoved; + Client *next; + Client *snext; + Monitor *mon; + Window win; +}; + +typedef struct { + unsigned int mod; + KeySym keysym; + void (*func)(const Arg *); + const Arg arg; +} Key; + +typedef struct { + const char *symbol; + void (*arrange)(Monitor *); +} Layout; + +typedef struct { + const char *class; + const char *instance; + const char *title; + unsigned int tags; + int iscentered; + int isfloating; + int monitor; +} Rule; + +typedef struct Systray Systray; +struct Systray { + Window win; + Client *icons; +}; + +typedef struct { + const char** command; + const char* name; +} Launcher; + +/* function declarations */ +static void applyrules(Client *c); +static int applysizehints(Client *c, int *x, int *y, int *w, int *h, + int interact); +static void arrange(Monitor *m); +static void arrangemon(Monitor *m); +static void attach(Client *c); +static void attachstack(Client *c); +static void buttonpress(XEvent *e); +static void checkotherwm(void); +static void cleanup(void); +static void cleanupmon(Monitor *mon); +static void clientmessage(XEvent *e); +static void configure(Client *c); +static void configurenotify(XEvent *e); +static void configurerequest(XEvent *e); +static Monitor *createmon(void); +static void cyclelayout(const Arg *arg); +static void destroynotify(XEvent *e); +static void detach(Client *c); +static void detachstack(Client *c); +static Monitor *dirtomon(int dir); +static void dragmfact(const Arg *arg); +static void dragcfact(const Arg *arg); +static void drawbar(Monitor *m); +static void drawbars(void); +static int drawstatusbar(Monitor *m, int bh, char *text); +static void drawtab(Monitor *m); +static void drawtabs(void); +static void enternotify(XEvent *e); +static void expose(XEvent *e); +static void focus(Client *c); +static void focusin(XEvent *e); +static void focusmon(const Arg *arg); +static void focusstack(const Arg *arg); +static void focuswin(const Arg *arg); +static Atom getatomprop(Client *c, Atom prop); +static Picture geticonprop(Window w, unsigned int *icw, unsigned int *ich); +static int getrootptr(int *x, int *y); +static long getstate(Window w); +static unsigned int getsystraywidth(); +static int gettextprop(Window w, Atom atom, char *text, unsigned int size); +static void grabbuttons(Client *c, int focused); +static void grabkeys(void); +static void hide(Client *c); +static void incnmaster(const Arg *arg); +static void keypress(XEvent *e); +static void killclient(const Arg *arg); +static void manage(Window w, XWindowAttributes *wa); +static void mappingnotify(XEvent *e); +static void maprequest(XEvent *e); +static void monocle(Monitor *m); +static void motionnotify(XEvent *e); +static void movemouse(const Arg *arg); +static void moveorplace(const Arg *arg); +static Client *nexttiled(Client *c); +static void placemouse(const Arg *arg); +static void pop(Client *c); +static void propertynotify(XEvent *e); +static void restart(const Arg *arg); +static Client *recttoclient(int x, int y, int w, int h); +static Monitor *recttomon(int x, int y, int w, int h); +static void removesystrayicon(Client *i); +static void resize(Client *c, int x, int y, int w, int h, int interact); +static void resizebarwin(Monitor *m); +static void resizeclient(Client *c, int x, int y, int w, int h); +static void resizemouse(const Arg *arg); +static void resizerequest(XEvent *e); +static void restack(Monitor *m); +static void run(void); +static void scan(void); +static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, + long d3, long d4); +static void sendmon(Client *c, Monitor *m); +static void setborderpx(const Arg *arg); +static void setclientstate(Client *c, long state); +static void setclienttagprop(Client *c); +static void setcurrentdesktop(void); +static void setdesktopnames(void); +static void setfocus(Client *c); +static void setfullscreen(Client *c, int fullscreen); +static void setlayout(const Arg *arg); +static void setcfact(const Arg *arg); +static void setmfact(const Arg *arg); +static void setnumdesktops(void); +static void setup(void); +static void setviewport(void); +static void seturgent(Client *c, int urg); +static void show(Client *c); +static void showhide(Client *c); +static void showtagpreview(int tag); +static void sigchld(int unused); +static void spawn(const Arg *arg); +static void switchtag(void); +static Monitor *systraytomon(Monitor *m); +static void tabmode(const Arg *arg); +static void tag(const Arg *arg); +static void tagmon(const Arg *arg); +static void togglebar(const Arg *arg); +static void togglefloating(const Arg *arg); +static void togglefullscr(const Arg *arg); +static void toggletag(const Arg *arg); +static void toggleview(const Arg *arg); +static void freeicon(Client *c); +static void hidewin(const Arg *arg); +static void restorewin(const Arg *arg); +static void unfocus(Client *c, int setfocus); +static void unmanage(Client *c, int destroyed); +static void unmapnotify(XEvent *e); +static void updatecurrentdesktop(void); +static void updatebarpos(Monitor *m); +static void updatebars(void); +static void updatepreview(void); +static void updateclientlist(void); +static int updategeom(void); +static void updatenumlockmask(void); +static void updatesizehints(Client *c); +static void updatestatus(void); +static void updatesystray(void); +static void updatesystrayicongeom(Client *i, int w, int h); +static void updatesystrayiconstate(Client *i, XPropertyEvent *ev); +static void updatetitle(Client *c); +static void updateicon(Client *c); +static void updatewindowtype(Client *c); +static void updatewmhints(Client *c); +static void view(const Arg *arg); +static Client *wintoclient(Window w); +static Monitor *wintomon(Window w); +static Client *wintosystrayicon(Window w); +static int xerror(Display *dpy, XErrorEvent *ee); +static int xerrordummy(Display *dpy, XErrorEvent *ee); +static int xerrorstart(Display *dpy, XErrorEvent *ee); +static void zoom(const Arg *arg); + +/* variables */ +static Systray *systray = NULL; +static const char broken[] = "broken"; +static char stext[1024]; +static int screen; +static int sw, sh; /* X display screen geometry width, height */ +static int bh; /* bar height */ +static int th = 0; /* tab bar geometry */ +static int lrpad; /* sum of left and right padding for text */ +static int (*xerrorxlib)(Display *, XErrorEvent *); +static unsigned int numlockmask = 0; +static void (*handler[LASTEvent])(XEvent *) = { + [ButtonPress] = buttonpress, + [ClientMessage] = clientmessage, + [ConfigureRequest] = configurerequest, + [ConfigureNotify] = configurenotify, + [DestroyNotify] = destroynotify, + [EnterNotify] = enternotify, + [Expose] = expose, + [FocusIn] = focusin, + [KeyPress] = keypress, + [MappingNotify] = mappingnotify, + [MapRequest] = maprequest, + [MotionNotify] = motionnotify, + [PropertyNotify] = propertynotify, + [ResizeRequest] = resizerequest, + [UnmapNotify] = unmapnotify}; +static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast]; +static int running = 1; +static Cur *cursor[CurLast]; +static Clr **scheme, clrborder; +static Display *dpy; +static Drw *drw; +static Monitor *mons, *selmon; +static Window root, wmcheckwin; + +#define hiddenWinStackMax 100 +static int hiddenWinStackTop = -1; +static Client* hiddenWinStack[hiddenWinStackMax]; + +/* configuration, allows nested code to access above variables */ +#include "config.h" + +typedef struct Pertag Pertag; +struct Monitor { + char ltsymbol[16]; + float mfact; + int nmaster; + int num; + int by; /* bar geometry */ + int ty; /* tab bar geometry */ + int mx, my, mw, mh; /* screen size */ + int wx, wy, ww, wh; /* window area */ + int gappih; /* horizontal gap between windows */ + int gappiv; /* vertical gap between windows */ + int gappoh; /* horizontal outer gaps */ + int gappov; /* vertical outer gaps */ + unsigned int borderpx; + unsigned int seltags; + unsigned int sellt; + unsigned int tagset[2]; + unsigned int colorfultag; + int showbar, showtab; + int topbar, toptab; + Client *clients; + Client *sel; + Client *stack; + Monitor *next; + Window barwin; + Window tabwin; + Window tagwin; + Pixmap tagmap[LENGTH(tags)]; + int previewshow; + int ntabs; + int tab_widths[MAXTABS]; + int tab_btn_w[3]; + const Layout *lt[2]; + Pertag *pertag; +}; + +#include "vanitygaps.c" +#include "movestack.c" + +struct Pertag { + unsigned int curtag, prevtag; /* current and previous tag */ + int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */ + float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */ + unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */ + const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */ + int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */ +}; + +/* compile-time check if all tags fit into an unsigned int bit array. */ +struct NumTags { + char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; +}; + +/* function implementations */ +void applyrules(Client *c) { + const char *class, *instance; + unsigned int i; + const Rule *r; + Monitor *m; + XClassHint ch = {NULL, NULL}; + + /* rule matching */ + c->iscentered = 0; + c->isfloating = 0; + c->tags = 0; + XGetClassHint(dpy, c->win, &ch); + class = ch.res_class ? ch.res_class : broken; + instance = ch.res_name ? ch.res_name : broken; + + for (i = 0; i < LENGTH(rules); i++) { + r = &rules[i]; + if ((!r->title || strstr(c->name, r->title)) && + (!r->class || strstr(class, r->class)) && + (!r->instance || strstr(instance, r->instance))) { + c->iscentered = r->iscentered; + c->isfloating = r->isfloating; + c->tags |= r->tags; + for (m = mons; m && m->num != r->monitor; m = m->next) + ; + if (m) + c->mon = m; + } + } + if (ch.res_class) + XFree(ch.res_class); + if (ch.res_name) + XFree(ch.res_name); + c->tags = + c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags]; +} + +int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact) { + int baseismin; + Monitor *m = c->mon; + + /* set minimum possible */ + *w = MAX(1, *w); + *h = MAX(1, *h); + if (interact) { + if (*x > sw) + *x = sw - WIDTH(c); + if (*y > sh) + *y = sh - HEIGHT(c); + if (*x + *w + 2 * c->bw < 0) + *x = 0; + if (*y + *h + 2 * c->bw < 0) + *y = 0; + } else { + if (*x >= m->wx + m->ww) + *x = m->wx + m->ww - WIDTH(c); + if (*y >= m->wy + m->wh) + *y = m->wy + m->wh - HEIGHT(c); + if (*x + *w + 2 * c->bw <= m->wx) + *x = m->wx; + if (*y + *h + 2 * c->bw <= m->wy) + *y = m->wy; + } + if (*h < bh) + *h = bh; + if (*w < bh) + *w = bh; + if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) { + if (!c->hintsvalid) + updatesizehints(c); + /* see last two sentences in ICCCM 4.1.2.3 */ + baseismin = c->basew == c->minw && c->baseh == c->minh; + if (!baseismin) { /* temporarily remove base dimensions */ + *w -= c->basew; + *h -= c->baseh; + } + /* adjust for aspect limits */ + if (c->mina > 0 && c->maxa > 0) { + if (c->maxa < (float)*w / *h) + *w = *h * c->maxa + 0.5; + else if (c->mina < (float)*h / *w) + *h = *w * c->mina + 0.5; + } + if (baseismin) { /* increment calculation requires this */ + *w -= c->basew; + *h -= c->baseh; + } + /* adjust for increment value */ + if (c->incw) + *w -= *w % c->incw; + if (c->inch) + *h -= *h % c->inch; + /* restore base dimensions */ + *w = MAX(*w + c->basew, c->minw); + *h = MAX(*h + c->baseh, c->minh); + if (c->maxw) + *w = MIN(*w, c->maxw); + if (c->maxh) + *h = MIN(*h, c->maxh); + } + return *x != c->x || *y != c->y || *w != c->w || *h != c->h; +} + +void arrange(Monitor *m) { + if (m) + showhide(m->stack); + else + for (m = mons; m; m = m->next) + showhide(m->stack); + if (m) { + arrangemon(m); + restack(m); + } else + for (m = mons; m; m = m->next) + arrangemon(m); +} + +void arrangemon(Monitor *m) { + updatebarpos(m); + updatesystray(); + XMoveResizeWindow(dpy, m->tabwin, m->wx + m->gappov, m->ty, m->ww - 2 * m->gappov, th); + XMoveWindow(dpy, m->tagwin, m->wx + m->gappov, m->by + (m->topbar ? (bh + m->gappoh) : (- (m->mh / scalepreview) - m->gappoh))); + strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); + if (m->lt[m->sellt]->arrange) + m->lt[m->sellt]->arrange(m); +} + +void attach(Client *c) { + if(new_window_attach_on_end){ + Client**tmp = &c->mon->clients; + while(*tmp)tmp = &(*tmp)->next; + *tmp = c; + }else{ + c->next = c->mon->clients; + c->mon->clients = c; + } +} + +void attachstack(Client *c) { + c->snext = c->mon->stack; + c->mon->stack = c; +} + +void buttonpress(XEvent *e) { + unsigned int i, x, click; + int loop; + Arg arg = {0}; + Client *c; + Monitor *m; + XButtonPressedEvent *ev = &e->xbutton; + + click = ClkRootWin; + /* focus monitor if necessary */ + if ((m = wintomon(ev->window)) && m != selmon) { + unfocus(selmon->sel, 1); + selmon = m; + focus(NULL); + } + if (ev->window == selmon->barwin) { + if (selmon->previewshow) { + XUnmapWindow(dpy, selmon->tagwin); + selmon->previewshow = 0; + } + i = x = 0; + do + x += TEXTW(tags[i]); + while (ev->x >= x && ++i < LENGTH(tags)); + if (i < LENGTH(tags)) { + click = ClkTagBar; + arg.ui = 1 << i; + goto execute_handler; + } else if (ev->x < x + TEXTW(selmon->ltsymbol)) { + click = ClkLtSymbol; + goto execute_handler; + } + + x += TEXTW(selmon->ltsymbol); + + for(i = 0; i < LENGTH(launchers); i++) { + x += TEXTW(launchers[i].name); + + if (ev->x < x) { + Arg a; + a.v = launchers[i].command; + spawn(&a); + return; + } + } + + if (ev->x > selmon->ww - (int)TEXTW(stext)) + click = ClkStatusText; + else + click = ClkWinTitle; + } + + if(ev->window == selmon->tabwin) { + i = 0; x = 0; + for(c = selmon->clients; c; c = c->next){ + if(!ISVISIBLE(c)) continue; + x += selmon->tab_widths[i]; + if (ev->x > x) + ++i; + else + break; + if(i >= m->ntabs) break; + } + if(c && ev->x <= x) { + click = ClkTabBar; + arg.ui = i; + } else { + x = selmon->ww - 2 * m->gappov; + for (loop = 2; loop >= 0; loop--) { + x -= selmon->tab_btn_w[loop]; + if (ev->x > x) + break; + } + if (ev->x >= x) + click = ClkTabPrev + loop; + } + } + else if((c = wintoclient(ev->window))) { + focus(c); + restack(selmon); + XAllowEvents(dpy, ReplayPointer, CurrentTime); + click = ClkClientWin; + } + +execute_handler: + + for (i = 0; i < LENGTH(buttons); i++) + if (click == buttons[i].click && buttons[i].func && + buttons[i].button == ev->button && + CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) + buttons[i].func( + ((click == ClkTagBar || click == ClkTabBar) && buttons[i].arg.i == 0) ? &arg : &buttons[i].arg); +} + +void checkotherwm(void) { + xerrorxlib = XSetErrorHandler(xerrorstart); + /* this causes an error if some other window manager is running */ + XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask); + XSync(dpy, False); + XSetErrorHandler(xerror); + XSync(dpy, False); +} + +void cleanup(void) { + Arg a = {.ui = ~0}; + Layout foo = {"", NULL}; + Monitor *m; + size_t i; + + view(&a); + selmon->lt[selmon->sellt] = &foo; + for (m = mons; m; m = m->next) + while (m->stack) + unmanage(m->stack, 0); + XUngrabKey(dpy, AnyKey, AnyModifier, root); + while (mons) + cleanupmon(mons); + if (showsystray) { + XUnmapWindow(dpy, systray->win); + XDestroyWindow(dpy, systray->win); + free(systray); + } + for (i = 0; i < CurLast; i++) + drw_cur_free(drw, cursor[i]); + for (i = 0; i < LENGTH(colors) + 1; i++) + free(scheme[i]); + free(scheme); + XDestroyWindow(dpy, wmcheckwin); + drw_free(drw); + XSync(dpy, False); + XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); + XDeleteProperty(dpy, root, netatom[NetActiveWindow]); +} + +void cleanupmon(Monitor *mon) { + Monitor *m; + size_t i; + + if (mon == mons) + mons = mons->next; + else { + for (m = mons; m && m->next != mon; m = m->next) + ; + m->next = mon->next; + } + for (i = 0; i < LENGTH(tags); i++) { + if (mon->tagmap[i]) + XFreePixmap(dpy, mon->tagmap[i]); + } + XUnmapWindow(dpy, mon->barwin); + XDestroyWindow(dpy, mon->barwin); + XUnmapWindow(dpy, mon->tabwin); + XDestroyWindow(dpy, mon->tabwin); + XUnmapWindow(dpy, mon->tagwin); + XDestroyWindow(dpy, mon->tagwin); + free(mon); +} + +void clientmessage(XEvent *e) { + XWindowAttributes wa; + XSetWindowAttributes swa; + XClientMessageEvent *cme = &e->xclient; + Client *c = wintoclient(cme->window); + + if (showsystray && cme->window == systray->win && + cme->message_type == netatom[NetSystemTrayOP]) { + /* add systray icons */ + if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) { + if (!(c = (Client *)calloc(1, sizeof(Client)))) + die("fatal: could not malloc() %u bytes\n", sizeof(Client)); + if (!(c->win = cme->data.l[2])) { + free(c); + return; + } + c->mon = selmon; + c->next = systray->icons; + systray->icons = c; + if (!XGetWindowAttributes(dpy, c->win, &wa)) { + /* use sane defaults */ + wa.width = bh; + wa.height = bh; + wa.border_width = 0; + } + c->x = c->oldx = c->y = c->oldy = 0; + c->w = c->oldw = wa.width; + c->h = c->oldh = wa.height; + c->oldbw = wa.border_width; + c->bw = 0; + c->isfloating = True; + /* reuse tags field as mapped status */ + c->tags = 1; + updatesizehints(c); + updatesystrayicongeom(c, wa.width, wa.height); + XAddToSaveSet(dpy, c->win); + XSelectInput(dpy, c->win, + StructureNotifyMask | PropertyChangeMask | + ResizeRedirectMask); + XClassHint ch = {"dwmsystray", "dwmsystray"}; + XSetClassHint(dpy, c->win, &ch); + XReparentWindow(dpy, c->win, systray->win, 0, 0); + /* use parents background color */ + swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; + XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa); + sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, + XEMBED_EMBEDDED_NOTIFY, 0, systray->win, + XEMBED_EMBEDDED_VERSION); + /* FIXME not sure if I have to send these events, too */ + sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, + XEMBED_FOCUS_IN, 0, systray->win, XEMBED_EMBEDDED_VERSION); + sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, + XEMBED_WINDOW_ACTIVATE, 0, systray->win, + XEMBED_EMBEDDED_VERSION); + sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, + XEMBED_MODALITY_ON, 0, systray->win, XEMBED_EMBEDDED_VERSION); + XSync(dpy, False); + resizebarwin(selmon); + updatesystray(); + setclientstate(c, NormalState); + } + return; + } + if (!c) + return; + if (cme->message_type == netatom[NetWMState]) { + if (cme->data.l[1] == netatom[NetWMFullscreen] || + cme->data.l[2] == netatom[NetWMFullscreen]) + setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ + || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && + !c->isfullscreen))); + } else if (cme->message_type == netatom[NetActiveWindow]) { + if (c != selmon->sel && !c->isurgent) + seturgent(c, 1); + } +} + +void configure(Client *c) { + XConfigureEvent ce; + + ce.type = ConfigureNotify; + ce.display = dpy; + ce.event = c->win; + ce.window = c->win; + ce.x = c->x; + ce.y = c->y; + ce.width = c->w; + ce.height = c->h; + ce.border_width = c->bw; + ce.above = None; + ce.override_redirect = False; + XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce); +} + +void configurenotify(XEvent *e) { + Monitor *m; + Client *c; + XConfigureEvent *ev = &e->xconfigure; + int dirty; + + /* TODO: updategeom handling sucks, needs to be simplified */ + if (ev->window == root) { + dirty = (sw != ev->width || sh != ev->height); + sw = ev->width; + sh = ev->height; + if (updategeom() || dirty) { + drw_resize(drw, sw, bh); + updatebars(); + for (m = mons; m; m = m->next) { + for (c = m->clients; c; c = c->next) + if (c->isfullscreen) + resizeclient(c, m->mx, m->my, m->mw, m->mh); + resizebarwin(m); + } + focus(NULL); + arrange(NULL); + } + } +} + +void configurerequest(XEvent *e) { + Client *c; + Monitor *m; + XConfigureRequestEvent *ev = &e->xconfigurerequest; + XWindowChanges wc; + + if ((c = wintoclient(ev->window))) { + if (ev->value_mask & CWBorderWidth) + c->bw = ev->border_width; + else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) { + m = c->mon; + if (ev->value_mask & CWX) { + c->oldx = c->x; + c->x = m->mx + ev->x; + } + if (ev->value_mask & CWY) { + c->oldy = c->y; + c->y = m->my + ev->y; + } + if (ev->value_mask & CWWidth) { + c->oldw = c->w; + c->w = ev->width; + } + if (ev->value_mask & CWHeight) { + c->oldh = c->h; + c->h = ev->height; + } + if ((c->x + c->w) > m->mx + m->mw && c->isfloating) + c->x = m->mx + (m->mw / 2 - WIDTH(c) / 2); /* center in x direction */ + if ((c->y + c->h) > m->my + m->mh && c->isfloating) + c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */ + if ((ev->value_mask & (CWX | CWY)) && + !(ev->value_mask & (CWWidth | CWHeight))) + configure(c); + if (ISVISIBLE(c)) + XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); + } else + configure(c); + } else { + wc.x = ev->x; + wc.y = ev->y; + wc.width = ev->width; + wc.height = ev->height; + wc.border_width = ev->border_width; + wc.sibling = ev->above; + wc.stack_mode = ev->detail; + XConfigureWindow(dpy, ev->window, ev->value_mask, &wc); + } + XSync(dpy, False); +} + +Monitor *createmon(void) { + Monitor *m; + size_t i; + + m = ecalloc(1, sizeof(Monitor)); + m->tagset[0] = m->tagset[1] = 1; + m->mfact = mfact; + m->nmaster = nmaster; + m->showbar = showbar; + m->showtab = showtab; + m->topbar = topbar; + m->toptab = toptab; + m->ntabs = 0; + m->colorfultag = colorfultag ? colorfultag : 0; + m->gappih = gappih; + m->gappiv = gappiv; + m->gappoh = gappoh; + m->gappov = gappov; + m->borderpx = borderpx; + m->lt[0] = &layouts[0]; + m->lt[1] = &layouts[1 % LENGTH(layouts)]; + for (i = 0; i < LENGTH(tags); i++) + m->tagmap[i] = 0; + m->previewshow = 0; + strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); + m->pertag = ecalloc(1, sizeof(Pertag)); + m->pertag->curtag = m->pertag->prevtag = 1; + + for (i = 0; i <= LENGTH(tags); i++) { + m->pertag->nmasters[i] = m->nmaster; + m->pertag->mfacts[i] = m->mfact; + + m->pertag->ltidxs[i][0] = m->lt[0]; + m->pertag->ltidxs[i][1] = m->lt[1]; + m->pertag->sellts[i] = m->sellt; + + m->pertag->showbars[i] = m->showbar; + } + + return m; +} + +void cyclelayout(const Arg *arg) { + Layout *l; + for (l = (Layout *)layouts; l != selmon->lt[selmon->sellt]; l++) + ; + if (arg->i > 0) { + if (l->symbol && (l + 1)->symbol) + setlayout(&((Arg){.v = (l + 1)})); + else + setlayout(&((Arg){.v = layouts})); + } else { + if (l != layouts && (l - 1)->symbol) + setlayout(&((Arg){.v = (l - 1)})); + else + setlayout(&((Arg){.v = &layouts[LENGTH(layouts) - 2]})); + } +} + +void destroynotify(XEvent *e) { + Client *c; + XDestroyWindowEvent *ev = &e->xdestroywindow; + + if ((c = wintoclient(ev->window))) + unmanage(c, 1); + else if ((c = wintosystrayicon(ev->window))) { + removesystrayicon(c); + resizebarwin(selmon); + updatesystray(); + } +} + +void detach(Client *c) { + Client **tc; + + for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next) + ; + *tc = c->next; +} + +void detachstack(Client *c) { + Client **tc, *t; + + for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext) + ; + *tc = c->snext; + + if (c == c->mon->sel) { + for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext) + ; + c->mon->sel = t; + } +} + +Monitor *dirtomon(int dir) { + Monitor *m = NULL; + + if (dir > 0) { + if (!(m = selmon->next)) + m = mons; + } else if (selmon == mons) + for (m = mons; m->next; m = m->next) + ; + else + for (m = mons; m->next != selmon; m = m->next) + ; + return m; +} + +int drawstatusbar(Monitor *m, int bh, char *stext) { + int ret, i, w, x, len; + short isCode = 0; + char *text; + char *p; + + len = strlen(stext) + 1; + if (!(text = (char *)malloc(sizeof(char) * len))) + die("malloc"); + p = text; + memcpy(text, stext, len); + + /* compute width of the status text */ + w = 0; + i = -1; + while (text[++i]) { + if (text[i] == '^') { + if (!isCode) { + isCode = 1; + text[i] = '\0'; + w += TEXTW(text) - lrpad; + text[i] = '^'; + if (text[++i] == 'f') + w += atoi(text + ++i); + } else { + isCode = 0; + text = text + i + 1; + i = -1; + } + } + } + if (!isCode) + w += TEXTW(text) - lrpad; + else + isCode = 0; + text = p; + + w += horizpadbar; + if(floatbar){ + ret = x = m->ww - m->gappov * 2 - borderpx - w; + x = m->ww - m->gappov * 2 - borderpx - w - getsystraywidth(); + }else{ + ret = x = m->ww - borderpx - w; + x = m->ww - w - getsystraywidth(); + } + + drw_setscheme(drw, scheme[LENGTH(colors)]); + drw->scheme[ColFg] = scheme[SchemeNorm][ColFg]; + drw->scheme[ColBg] = scheme[SchemeNorm][ColBg]; + drw_rect(drw, x, borderpx, w, bh, 1, 1); + x += horizpadbar / 2; + + /* process status text */ + i = -1; + while (text[++i]) { + if (text[i] == '^' && !isCode) { + isCode = 1; + + text[i] = '\0'; + w = TEXTW(text) - lrpad; + drw_text(drw, x, borderpx + vertpadbar / 2, w, bh - vertpadbar, 0, text, + 0); + + x += w; + + /* process code */ + while (text[++i] != '^') { + if (text[i] == 'c') { + char buf[8]; + memcpy(buf, (char *)text + i + 1, 7); + buf[7] = '\0'; + drw_clr_create(drw, &drw->scheme[ColFg], buf); + i += 7; + } else if (text[i] == 'b') { + char buf[8]; + memcpy(buf, (char *)text + i + 1, 7); + buf[7] = '\0'; + drw_clr_create(drw, &drw->scheme[ColBg], buf); + i += 7; + } else if (text[i] == 'd') { + drw->scheme[ColFg] = scheme[SchemeNorm][ColFg]; + drw->scheme[ColBg] = scheme[SchemeNorm][ColBg]; + } else if (text[i] == 'r') { + int rx = atoi(text + ++i); + while (text[++i] != ',') + ; + int ry = atoi(text + ++i); + while (text[++i] != ',') + ; + int rw = atoi(text + ++i); + while (text[++i] != ',') + ; + int rh = atoi(text + ++i); + + drw_rect(drw, rx + x, ry + borderpx + vertpadbar / 2, rw, rh, 1, 0); + } else if (text[i] == 'f') { + x += atoi(text + ++i); + } + } + + text = text + i + 1; + i = -1; + isCode = 0; + } + } + + if (!isCode) { + w = TEXTW(text) - lrpad; + drw_text(drw, x, borderpx + vertpadbar / 2, w, bh - vertpadbar, 0, text, 0); + } + + drw_setscheme(drw, scheme[SchemeNorm]); + free(p); + + return ret; +} + +void dragcfact(const Arg *arg) { + int prev_x, prev_y, dist_x, dist_y; + float fact; + Client *c; + XEvent ev; + Time lasttime = 0; + + if (!(c = selmon->sel)) + return; + if (c->isfloating) { + resizemouse(arg); + return; + } +#if !FAKEFULLSCREEN_PATCH +#if FAKEFULLSCREEN_CLIENT_PATCH + if (c->isfullscreen && + !c->fakefullscreen) /* no support resizing fullscreen windows by mouse */ + return; +#else + if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */ + return; +#endif // FAKEFULLSCREEN_CLIENT_PATCH +#endif // !FAKEFULLSCREEN_PATCH + restack(selmon); + + if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, + None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess) + return; + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); + + prev_x = prev_y = -999999; + + do { + XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); + switch (ev.type) { + case ConfigureRequest: + case Expose: + case MapRequest: + handler[ev.type](&ev); + break; + case MotionNotify: + if ((ev.xmotion.time - lasttime) <= (1000 / 120)) + continue; + lasttime = ev.xmotion.time; + if (prev_x == -999999) { + prev_x = ev.xmotion.x_root; + prev_y = ev.xmotion.y_root; + } + + dist_x = ev.xmotion.x - prev_x; + dist_y = ev.xmotion.y - prev_y; + + if (abs(dist_x) > abs(dist_y)) { + fact = (float)4.0 * dist_x / c->mon->ww; + } else { + fact = (float)-4.0 * dist_y / c->mon->wh; + } + + if (fact) + setcfact(&((Arg){.f = fact})); + + prev_x = ev.xmotion.x; + prev_y = ev.xmotion.y; + break; + } + } while (ev.type != ButtonRelease); + + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w / 2, c->h / 2); + + XUngrabPointer(dpy, CurrentTime); + while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)) + ; +} + +void dragmfact(const Arg *arg) { + unsigned int n; + int py, px; // pointer coordinates + int ax, ay, aw, ah; // area position, width and height + int center = 0, horizontal = 0, mirror = 0, fixed = 0; // layout configuration + double fact; + Monitor *m; + XEvent ev; + Time lasttime = 0; + + m = selmon; + +#if VANITYGAPS_PATCH + int oh, ov, ih, iv; + getgaps(m, &oh, &ov, &ih, &iv, &n); +#else + Client *c; + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) + ; +#endif // VANITYGAPS_PATCH + + ax = m->wx; + ay = m->wy; + ah = m->wh; + aw = m->ww; + + if (!n) + return; +#if FLEXTILE_DELUXE_LAYOUT + else if (m->lt[m->sellt]->arrange == &flextile) { + int layout = m->ltaxis[LAYOUT]; + if (layout < 0) { + mirror = 1; + layout *= -1; + } + if (layout > FLOATING_MASTER) { + layout -= FLOATING_MASTER; + fixed = 1; + } + + if (layout == SPLIT_HORIZONTAL || layout == SPLIT_HORIZONTAL_DUAL_STACK) + horizontal = 1; + else if (layout == SPLIT_CENTERED_VERTICAL && (fixed || n - m->nmaster > 1)) + center = 1; + else if (layout == FLOATING_MASTER) { + center = 1; + if (aw < ah) + horizontal = 1; + } else if (layout == SPLIT_CENTERED_HORIZONTAL) { + if (fixed || n - m->nmaster > 1) + center = 1; + horizontal = 1; + } + } +#endif // FLEXTILE_DELUXE_LAYOUT +#if CENTEREDMASTER_LAYOUT + else if (m->lt[m->sellt]->arrange == ¢eredmaster && + (fixed || n - m->nmaster > 1)) + center = 1; +#endif // CENTEREDMASTER_LAYOUT +#if CENTEREDFLOATINGMASTER_LAYOUT + else if (m->lt[m->sellt]->arrange == ¢eredfloatingmaster) + center = 1; +#endif // CENTEREDFLOATINGMASTER_LAYOUT +#if BSTACK_LAYOUT + else if (m->lt[m->sellt]->arrange == &bstack) + horizontal = 1; +#endif // BSTACK_LAYOUT +#if BSTACKHORIZ_LAYOUT + else if (m->lt[m->sellt]->arrange == &bstackhoriz) + horizontal = 1; +#endif // BSTACKHORIZ_LAYOUT + + /* do not allow mfact to be modified under certain conditions */ + if (!m->lt[m->sellt]->arrange // floating layout + || (!fixed && m->nmaster && n <= m->nmaster) // no master +#if MONOCLE_LAYOUT + || m->lt[m->sellt]->arrange == &monocle +#endif // MONOCLE_LAYOUT +#if GRIDMODE_LAYOUT + || m->lt[m->sellt]->arrange == &grid +#endif // GRIDMODE_LAYOUT +#if HORIZGRID_LAYOUT + || m->lt[m->sellt]->arrange == &horizgrid +#endif // HORIZGRID_LAYOUT +#if GAPPLESSGRID_LAYOUT + || m->lt[m->sellt]->arrange == &gaplessgrid +#endif // GAPPLESSGRID_LAYOUT +#if NROWGRID_LAYOUT + || m->lt[m->sellt]->arrange == &nrowgrid +#endif // NROWGRID_LAYOUT +#if FLEXTILE_DELUXE_LAYOUT + || + (m->lt[m->sellt]->arrange == &flextile && m->ltaxis[LAYOUT] == NO_SPLIT) +#endif // FLEXTILE_DELUXE_LAYOUT + ) + return; + +#if VANITYGAPS_PATCH + ay += oh; + ax += ov; + aw -= 2 * ov; + ah -= 2 * oh; +#endif // VANITYGAPS_PATCH + + if (center) { + if (horizontal) { + px = ax + aw / 2; +#if VANITYGAPS_PATCH + py = ay + ah / 2 + (ah - 2 * ih) * (m->mfact / 2.0) + ih / 2; +#else + py = ay + ah / 2 + ah * m->mfact / 2.0; +#endif // VANITYGAPS_PATCH + } else { // vertical split +#if VANITYGAPS_PATCH + px = ax + aw / 2 + (aw - 2 * iv) * m->mfact / 2.0 + iv / 2; +#else + px = ax + aw / 2 + aw * m->mfact / 2.0; +#endif // VANITYGAPS_PATCH + py = ay + ah / 2; + } + } else if (horizontal) { + px = ax + aw / 2; + if (mirror) +#if VANITYGAPS_PATCH + py = ay + (ah - ih) * (1.0 - m->mfact) + ih / 2; +#else + py = ay + (ah * (1.0 - m->mfact)); +#endif // VANITYGAPS_PATCH + else +#if VANITYGAPS_PATCH + py = ay + ((ah - ih) * m->mfact) + ih / 2; +#else + py = ay + (ah * m->mfact); +#endif // VANITYGAPS_PATCH + } else { // vertical split + if (mirror) +#if VANITYGAPS_PATCH + px = ax + (aw - iv) * (1.0 - m->mfact) + iv / 2; +#else + px = ax + (aw * m->mfact); +#endif // VANITYGAPS_PATCH + else +#if VANITYGAPS_PATCH + px = ax + ((aw - iv) * m->mfact) + iv / 2; +#else + px = ax + (aw * m->mfact); +#endif // VANITYGAPS_PATCH + py = ay + ah / 2; + } + + if (XGrabPointer( + dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, None, + cursor[horizontal ? CurResizeVertArrow : CurResizeHorzArrow]->cursor, + CurrentTime) != GrabSuccess) + return; + XWarpPointer(dpy, None, root, 0, 0, 0, 0, px, py); + + do { + XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); + switch (ev.type) { + case ConfigureRequest: + case Expose: + case MapRequest: + handler[ev.type](&ev); + break; + case MotionNotify: + if ((ev.xmotion.time - lasttime) <= (1000 / 40)) + continue; + if (lasttime != 0) { + px = ev.xmotion.x; + py = ev.xmotion.y; + } + lasttime = ev.xmotion.time; + +#if VANITYGAPS_PATCH + if (center) + if (horizontal) + if (py - ay > ah / 2) + fact = (double)1.0 - + (ay + ah - py - ih / 2) * 2 / (double)(ah - 2 * ih); + else + fact = (double)1.0 - (py - ay - ih / 2) * 2 / (double)(ah - 2 * ih); + else if (px - ax > aw / 2) + fact = + (double)1.0 - (ax + aw - px - iv / 2) * 2 / (double)(aw - 2 * iv); + else + fact = (double)1.0 - (px - ax - iv / 2) * 2 / (double)(aw - 2 * iv); + else if (horizontal) + fact = (double)(py - ay - ih / 2) / (double)(ah - ih); + else + fact = (double)(px - ax - iv / 2) / (double)(aw - iv); +#else + if (center) + if (horizontal) + if (py - ay > ah / 2) + fact = (double)1.0 - (ay + ah - py) * 2 / (double)ah; + else + fact = (double)1.0 - (py - ay) * 2 / (double)ah; + else if (px - ax > aw / 2) + fact = (double)1.0 - (ax + aw - px) * 2 / (double)aw; + else + fact = (double)1.0 - (px - ax) * 2 / (double)aw; + else if (horizontal) + fact = (double)(py - ay) / (double)ah; + else + fact = (double)(px - ax) / (double)aw; +#endif // VANITYGAPS_PATCH + + if (!center && mirror) + fact = 1.0 - fact; + + setmfact(&((Arg){.f = 1.0 + fact})); + px = ev.xmotion.x; + py = ev.xmotion.y; + break; + } + } while (ev.type != ButtonRelease); + + XUngrabPointer(dpy, CurrentTime); + while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)) + ; +} + +void drawbar(Monitor *m) { + int x, y = borderpx, w, sw = 0, stw = 0; + int bh_n = bh - borderpx * 2; + int mw; + if(floatbar){ + mw = m->ww - m->gappov * 2 - borderpx * 2; + }else{ + mw = m->ww - borderpx * 2; + } + int boxs = drw->fonts->h / 9; + int boxw = drw->fonts->h / 6 + 2; + unsigned int i, occ = 0, urg = 0; + Client *c; + + XSetForeground(drw->dpy, drw->gc, clrborder.pixel); + if(floatbar){ + XFillRectangle(drw->dpy, drw->drawable, drw->gc, 0, 0, m->ww - m->gappov * 2, bh); + }else{ + XFillRectangle(drw->dpy, drw->drawable, drw->gc, 0, 0, m->ww, bh); + } + + if (showsystray && m == systraytomon(m)) + stw = getsystraywidth(); + + if (!m->showbar) + return; + + /* draw status first so it can be overdrawn by tags later */ + if (m == selmon) { /* status is only drawn on selected monitor */ + sw = mw - drawstatusbar(m, bh_n, stext); + } + + resizebarwin(m); + for (c = m->clients; c; c = c->next) { + occ |= c->tags; + if (c->isurgent) + urg |= c->tags; + } + x = borderpx; + for (i = 0; i < LENGTH(tags); i++) { + w = TEXTW(tags[i]); + drw_setscheme(drw, scheme[occ & 1 << i ? (m->colorfultag ? tagschemes[i] : SchemeSel) : SchemeTag]); + drw_text(drw, x, y, w, bh_n, lrpad / 2, tags[i], urg & 1 << i); + if (ulineall || + m->tagset[m->seltags] & + 1 << i) /* if there are conflicts, just move these lines directly + underneath both 'drw_setscheme' and 'drw_text' :) */ + drw_rect(drw, x + ulinepad, bh_n - ulinestroke - ulinevoffset, + w - (ulinepad * 2), ulinestroke, 1, 0); + /*if (occ & 1 << i) + drw_rect(drw, x + boxs, y + boxs, boxw, boxw, + m == selmon && selmon->sel && selmon->sel->tags & 1 << i, + urg & 1 << i); */ + x += w; + } + w = TEXTW(m->ltsymbol); + drw_setscheme(drw, scheme[SchemeLayout]); + x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); + + for (i = 0; i < LENGTH(launchers); i++) + { + w = TEXTW(launchers[i].name); + drw_text(drw, x, 0, w, bh, lrpad / 2, launchers[i].name, urg & 1 << i); + x += w; + } + + w = floatbar?mw + m->gappov * 2 - sw - stw - x:mw - sw - stw - x; + if (w > bh_n) { + if (m->sel) { + drw_setscheme(drw, scheme[m == selmon ? SchemeTitle : SchemeNorm]); + drw_text(drw, x, 0, w, bh, lrpad / 2 + (m->sel->icon ? m->sel->icw + ICONSPACING : 0), m->sel->name, 0); + if (m->sel->icon) drw_pic(drw, x + lrpad / 2, (bh - m->sel->ich) / 2, m->sel->icw, m->sel->ich, m->sel->icon); + if (m->sel->isfloating) + drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); + } else { + drw_setscheme(drw, scheme[SchemeNorm]); + if(floatbar){ + drw_rect(drw, x, y, w - m->gappov * 2, bh_n, 1, 1); + }else{ + drw_rect(drw, x, y, w, bh_n, 1, 1); + } + } + } + drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh); +} + +static uint32_t prealpha(uint32_t p) { + uint8_t a = p >> 24u; + uint32_t rb = (a * (p & 0xFF00FFu)) >> 8u; + uint32_t g = (a * (p & 0x00FF00u)) >> 8u; + return (rb & 0xFF00FFu) | (g & 0x00FF00u) | (a << 24u); +} + +Picture +geticonprop(Window win, unsigned int *picw, unsigned int *pich) +{ + int format; + unsigned long n, extra, *p = NULL; + Atom real; + + if (XGetWindowProperty(dpy, win, netatom[NetWMIcon], 0L, LONG_MAX, False, AnyPropertyType, + &real, &format, &n, &extra, (unsigned char **)&p) != Success) + return None; + if (n == 0 || format != 32) { XFree(p); return None; } + + unsigned long *bstp = NULL; + uint32_t w, h, sz; + { + unsigned long *i; const unsigned long *end = p + n; + uint32_t bstd = UINT32_MAX, d, m; + for (i = p; i < end - 1; i += sz) { + if ((w = *i++) >= 16384 || (h = *i++) >= 16384) { XFree(p); return None; } + if ((sz = w * h) > end - i) break; + if ((m = w > h ? w : h) >= ICONSIZE && (d = m - ICONSIZE) < bstd) { bstd = d; bstp = i; } + } + if (!bstp) { + for (i = p; i < end - 1; i += sz) { + if ((w = *i++) >= 16384 || (h = *i++) >= 16384) { XFree(p); return None; } + if ((sz = w * h) > end - i) break; + if ((d = ICONSIZE - (w > h ? w : h)) < bstd) { bstd = d; bstp = i; } + } + } + if (!bstp) { XFree(p); return None; } + } + + if ((w = *(bstp - 2)) == 0 || (h = *(bstp - 1)) == 0) { XFree(p); return None; } + + uint32_t icw, ich; + if (w <= h) { + ich = ICONSIZE; icw = w * ICONSIZE / h; + if (icw == 0) icw = 1; + } + else { + icw = ICONSIZE; ich = h * ICONSIZE / w; + if (ich == 0) ich = 1; + } + *picw = icw; *pich = ich; + + uint32_t i, *bstp32 = (uint32_t *)bstp; + for (sz = w * h, i = 0; i < sz; ++i) bstp32[i] = prealpha(bstp[i]); + + Picture ret = drw_picture_create_resized(drw, (char *)bstp, w, h, icw, ich); + XFree(p); + + return ret; +} + + + +void drawbars(void) { + Monitor *m; + + for (m = mons; m; m = m->next) + drawbar(m); +} + +void +drawtabs(void) { + Monitor *m; + + for(m = mons; m; m = m->next) + drawtab(m); +} + +static int +cmpint(const void *p1, const void *p2) { + /* The actual arguments to this function are "pointers to + pointers to char", but strcmp(3) arguments are "pointers + to char", hence the following cast plus dereference */ + return *((int*) p1) > * (int*) p2; +} + + +void +drawtab(Monitor *m) { + Client *c; + int i; + char *btn_prev = ""; + char *btn_next = ""; + char *btn_close = " "; + int buttons_w = 0; + int sorted_label_widths[MAXTABS]; + int tot_width = 0; + int maxsize = bh; + int x = 0; + int w = 0; + int mw = floatbar?m->ww - 2 * m->gappov:m->ww; + buttons_w += TEXTW(btn_prev) - lrpad + horizpadtabo; + buttons_w += TEXTW(btn_next) - lrpad + horizpadtabo; + buttons_w += TEXTW(btn_close) - lrpad + horizpadtabo; + tot_width = buttons_w; + + /* Calculates number of labels and their width */ + m->ntabs = 0; + for(c = m->clients; c; c = c->next){ + if(!ISVISIBLE(c)) continue; + m->tab_widths[m->ntabs] = MIN(TEXTW(c->name) - lrpad + horizpadtabi + horizpadtabo, 250); + tot_width += m->tab_widths[m->ntabs]; + ++m->ntabs; + if(m->ntabs >= MAXTABS) break; + } + + if(tot_width > mw){ //not enough space to display the labels, they need to be truncated + memcpy(sorted_label_widths, m->tab_widths, sizeof(int) * m->ntabs); + qsort(sorted_label_widths, m->ntabs, sizeof(int), cmpint); + for(i = 0; i < m->ntabs; ++i){ + if(tot_width + (m->ntabs - i) * sorted_label_widths[i] > mw) + break; + tot_width += sorted_label_widths[i]; + } + maxsize = (mw - tot_width) / (m->ntabs - i); + maxsize = (m->ww - tot_width) / (m->ntabs - i); + } else{ + maxsize = mw; + } + i = 0; + + /* cleans window */ + drw_setscheme(drw, scheme[TabNorm]); + drw_rect(drw, 0, 0, mw, th, 1, 1); + + for(c = m->clients; c; c = c->next){ + if(!ISVISIBLE(c)) continue; + if(i >= m->ntabs) break; + if(m->tab_widths[i] > maxsize) m->tab_widths[i] = maxsize; + w = m->tab_widths[i]; + drw_setscheme(drw, scheme[(c == m->sel) ? TabSel : TabNorm]); + drw_text(drw, x + horizpadtabo / 2, vertpadbar / 2, w - horizpadtabo, th - vertpadbar, horizpadtabi / 2, c->name, 0); + x += w; + ++i; + } + + w = mw - buttons_w - x; + x += w; + drw_setscheme(drw, scheme[SchemeBtnPrev]); + w = TEXTW(btn_prev) - lrpad + horizpadtabo; + m->tab_btn_w[0] = w; + drw_text(drw, x + horizpadtabo / 2, vertpadbar / 2, w, th - vertpadbar, 0, btn_prev, 0); + x += w; + drw_setscheme(drw, scheme[SchemeBtnNext]); + w = TEXTW(btn_next) - lrpad + horizpadtabo; + m->tab_btn_w[1] = w; + drw_text(drw, x + horizpadtabo / 2, vertpadbar / 2, w, th - vertpadbar, 0, btn_next, 0); + x += w; + drw_setscheme(drw, scheme[SchemeBtnClose]); + w = TEXTW(btn_close) - lrpad + horizpadtabo; + m->tab_btn_w[2] = w; + drw_text(drw, x + horizpadtabo / 2, vertpadbar / 2, w, th - vertpadbar, 0, btn_close, 0); + x += w; + + drw_map(drw, m->tabwin, 0, 0, m->ww, th); +} + +void enternotify(XEvent *e) { + Client *c; + Monitor *m; + XCrossingEvent *ev = &e->xcrossing; + + if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && + ev->window != root) + return; + c = wintoclient(ev->window); + m = c ? c->mon : wintomon(ev->window); + if (m != selmon) { + unfocus(selmon->sel, 1); + selmon = m; + } else if (!c || c == selmon->sel) + return; + focus(c); +} + +void expose(XEvent *e) { + Monitor *m; + XExposeEvent *ev = &e->xexpose; + + if (ev->count == 0 && (m = wintomon(ev->window))) { + drawbar(m); + if (m == selmon) + updatesystray(); + } +} + +void focus(Client *c) { + if (!c || (!ISVISIBLE(c) || HIDDEN(c))) + for (c = selmon->stack; c && (!ISVISIBLE(c) || HIDDEN(c)); c = c->snext) + ; + if (selmon->sel && selmon->sel != c) + unfocus(selmon->sel, 0); + if (c) { + if (c->mon != selmon) + selmon = c->mon; + if (c->isurgent) + seturgent(c, 0); + detachstack(c); + attachstack(c); + grabbuttons(c, 1); + XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel); + setfocus(c); + } else { + XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); + XDeleteProperty(dpy, root, netatom[NetActiveWindow]); + } + selmon->sel = c; + drawbars(); + drawtabs(); +} + +/* there are some broken focus acquiring clients needing extra handling */ +void focusin(XEvent *e) { + XFocusChangeEvent *ev = &e->xfocus; + + if (selmon->sel && ev->window != selmon->sel->win) + setfocus(selmon->sel); +} + +void focusmon(const Arg *arg) { + Monitor *m; + + if (!mons->next) + return; + if ((m = dirtomon(arg->i)) == selmon) + return; + unfocus(selmon->sel, 0); + selmon = m; + focus(NULL); +} + +void focusstack(const Arg *arg) { + Client *c = NULL, *i; + + if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen)) + return; + if (arg->i > 0) { + for (c = selmon->sel->next; c && (!ISVISIBLE(c) || HIDDEN(c)); c = c->next) + ; + if (!c) + for (c = selmon->clients; c && (!ISVISIBLE(c) || HIDDEN(c)); c = c->next) + ; + } else { + for (i = selmon->clients; i != selmon->sel; i = i->next) + if (ISVISIBLE(i) && !HIDDEN(i)) + c = i; + if (!c) + for (; i; i = i->next) + if (ISVISIBLE(i) && !HIDDEN(i)) + c = i; + } + if (c) { + focus(c); + restack(selmon); + } +} + +void +focuswin(const Arg* arg){ + int iwin = arg->i; + Client* c = NULL; + for(c = selmon->clients; c && (iwin || !ISVISIBLE(c)) ; c = c->next){ + if(ISVISIBLE(c)) --iwin; + }; + if(c) { + focus(c); + restack(selmon); + } +} + +Atom getatomprop(Client *c, Atom prop) { + int di; + unsigned long dl; + unsigned char *p = NULL; + Atom da, atom = None; + /* FIXME getatomprop should return the number of items and a pointer to + * the stored data instead of this workaround */ + Atom req = XA_ATOM; + if (prop == xatom[XembedInfo]) + req = xatom[XembedInfo]; + + if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req, &da, + &di, &dl, &dl, &p) == Success && + p) { + atom = *(Atom *)p; + if (da == xatom[XembedInfo] && dl == 2) + atom = ((Atom *)p)[1]; + XFree(p); + } + return atom; +} + +int getrootptr(int *x, int *y) { + int di; + unsigned int dui; + Window dummy; + + return XQueryPointer(dpy, root, &dummy, &dummy, x, y, &di, &di, &dui); +} + +long getstate(Window w) { + int format; + long result = -1; + unsigned char *p = NULL; + unsigned long n, extra; + Atom real; + + if (XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, + wmatom[WMState], &real, &format, &n, &extra, + (unsigned char **)&p) != Success) + return -1; + if (n != 0) + result = *p; + XFree(p); + return result; +} + +unsigned int getsystraywidth() { + unsigned int w = 0; + Client *i; + if (showsystray) + for (i = systray->icons; i; w += i->w + systrayspacing, i = i->next) + ; + return w ? w + systrayspacing : 1; +} + +int gettextprop(Window w, Atom atom, char *text, unsigned int size) { + char **list = NULL; + int n; + XTextProperty name; + + if (!text || size == 0) + return 0; + text[0] = '\0'; + if (!XGetTextProperty(dpy, w, &name, atom) || !name.nitems) + return 0; + if (name.encoding == XA_STRING) { + strncpy(text, (char *)name.value, size - 1); + } else if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) { + strncpy(text, *list, size - 1); + XFreeStringList(list); + } + text[size - 1] = '\0'; + XFree(name.value); + return 1; +} + +void grabbuttons(Client *c, int focused) { + updatenumlockmask(); + { + unsigned int i, j; + unsigned int modifiers[] = {0, LockMask, numlockmask, + numlockmask | LockMask}; + XUngrabButton(dpy, AnyButton, AnyModifier, c->win); + if (!focused) + XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, BUTTONMASK, + GrabModeSync, GrabModeSync, None, None); + for (i = 0; i < LENGTH(buttons); i++) + if (buttons[i].click == ClkClientWin) + for (j = 0; j < LENGTH(modifiers); j++) + XGrabButton(dpy, buttons[i].button, buttons[i].mask | modifiers[j], + c->win, False, BUTTONMASK, GrabModeAsync, GrabModeSync, + None, None); + } +} + +void grabkeys(void) { + updatenumlockmask(); + { + unsigned int i, j; + unsigned int modifiers[] = {0, LockMask, numlockmask, + numlockmask | LockMask}; + KeyCode code; + + XUngrabKey(dpy, AnyKey, AnyModifier, root); + for (i = 0; i < LENGTH(keys); i++) + if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) + for (j = 0; j < LENGTH(modifiers); j++) + XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, True, + GrabModeAsync, GrabModeAsync); + } +} + +void +freeicon(Client *c) +{ + if (c->icon) { + XRenderFreePicture(dpy, c->icon); + c->icon = None; + } +} + +void +hide(Client *c) { + if (!c || HIDDEN(c)) + return; + + Window w = c->win; + static XWindowAttributes ra, ca; + + // more or less taken directly from blackbox's hide() function + XGrabServer(dpy); + XGetWindowAttributes(dpy, root, &ra); + XGetWindowAttributes(dpy, w, &ca); + // prevent UnmapNotify events + XSelectInput(dpy, root, ra.your_event_mask & ~SubstructureNotifyMask); + XSelectInput(dpy, w, ca.your_event_mask & ~StructureNotifyMask); + XUnmapWindow(dpy, w); + setclientstate(c, IconicState); + XSelectInput(dpy, root, ra.your_event_mask); + XSelectInput(dpy, w, ca.your_event_mask); + XUngrabServer(dpy); + + focus(c->snext); + arrange(c->mon); +} + +void incnmaster(const Arg *arg) { + selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0); + arrange(selmon); +} + +#ifdef XINERAMA +static int isuniquegeom(XineramaScreenInfo *unique, size_t n, + XineramaScreenInfo *info) { + while (n--) + if (unique[n].x_org == info->x_org && unique[n].y_org == info->y_org && + unique[n].width == info->width && unique[n].height == info->height) + return 0; + return 1; +} +#endif /* XINERAMA */ + +void keypress(XEvent *e) { + unsigned int i; + KeySym keysym; + XKeyEvent *ev; + + ev = &e->xkey; + keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); + for (i = 0; i < LENGTH(keys); i++) + if (keysym == keys[i].keysym && + CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) && keys[i].func) + keys[i].func(&(keys[i].arg)); +} + +void killclient(const Arg *arg) { + if (!selmon->sel) + return; + if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, + wmatom[WMDelete], CurrentTime, 0, 0, 0)) { + XGrabServer(dpy); + XSetErrorHandler(xerrordummy); + XSetCloseDownMode(dpy, DestroyAll); + XKillClient(dpy, selmon->sel->win); + XSync(dpy, False); + XSetErrorHandler(xerror); + XUngrabServer(dpy); + } +} + +void manage(Window w, XWindowAttributes *wa) { + Client *c, *t = NULL; + Window trans = None; + XWindowChanges wc; + + c = ecalloc(1, sizeof(Client)); + c->win = w; + /* geometry */ + c->x = c->oldx = wa->x; + c->y = c->oldy = wa->y; + c->w = c->oldw = wa->width; + c->h = c->oldh = wa->height; + c->oldbw = wa->border_width; + c->cfact = 1.0; + + updateicon(c); + updatetitle(c); + if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) { + c->mon = t->mon; + c->tags = t->tags; + } else { + c->mon = selmon; + applyrules(c); + } + + if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww) + c->x = c->mon->wx + c->mon->ww - WIDTH(c); + if (c->y + HEIGHT(c) > c->mon->wy + c->mon->wh) + c->y = c->mon->wy + c->mon->wh - HEIGHT(c); + c->x = MAX(c->x, c->mon->wx); + c->y = MAX(c->y, c->mon->wy); + c->bw = c->mon->borderpx; + + wc.border_width = c->bw; + XConfigureWindow(dpy, w, CWBorderWidth, &wc); + XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel); + configure(c); /* propagates border_width, if size doesn't change */ + updatewindowtype(c); + updatesizehints(c); + updatewmhints(c); + { + int format; + unsigned long *data, n, extra; + Monitor *m; + Atom atom; + if (XGetWindowProperty(dpy, c->win, netatom[NetClientInfo], 0L, 2L, False, XA_CARDINAL, + &atom, &format, &n, &extra, (unsigned char **)&data) == Success && n == 2) { + c->tags = *data; + for (m = mons; m; m = m->next) { + if (m->num == *(data+1)) { + c->mon = m; + break; + } + } + } + if (n > 0) + XFree(data); + } + setclienttagprop(c); + + if (c->iscentered) { + c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2; + c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2; + } + XSelectInput(dpy, w, + EnterWindowMask | FocusChangeMask | PropertyChangeMask | + StructureNotifyMask); + grabbuttons(c, 0); + if (!c->isfloating) + c->isfloating = c->oldstate = trans != None || c->isfixed; + if (c->isfloating) + XRaiseWindow(dpy, c->win); + attach(c); + attachstack(c); + XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, + PropModeAppend, (unsigned char *)&(c->win), 1); + XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, + c->h); /* some windows require this */ + if (!HIDDEN(c)) + setclientstate(c, NormalState); + if (c->mon == selmon) + unfocus(selmon->sel, 0); + c->mon->sel = c; + arrange(c->mon); + if (!HIDDEN(c)) + XMapWindow(dpy, c->win); + focus(NULL); +} + +void mappingnotify(XEvent *e) { + XMappingEvent *ev = &e->xmapping; + + XRefreshKeyboardMapping(ev); + if (ev->request == MappingKeyboard) + grabkeys(); +} + +void maprequest(XEvent *e) { + static XWindowAttributes wa; + XMapRequestEvent *ev = &e->xmaprequest; + Client *i; + if ((i = wintosystrayicon(ev->window))) { + sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, + XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION); + resizebarwin(selmon); + updatesystray(); + } + + if (!XGetWindowAttributes(dpy, ev->window, &wa) || wa.override_redirect) + return; + if (!wintoclient(ev->window)) + manage(ev->window, &wa); +} + +void +monocle(Monitor *m) +{ + unsigned int n = 0; + + Client *c; + + for (c = m->clients; c; c = c->next) + if (ISVISIBLE(c)) n++; + + if (n > 0) /* override layout symbol */ + snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); + + int newx, newy, neww, newh; + + for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) { + newx = m->wx + m->gappov - c->bw; + newy = m->wy + m->gappoh - c->bw; + neww = m->ww - 2 * (m->gappov + c->bw); + newh = m->wh - 2 * (m->gappoh + c->bw); + + applysizehints(c, &newx, &newy, &neww, &newh, 0); + + if (neww < m->ww) + newx = m->wx + (m->ww - (neww + 2 * c->bw)) / 2; + + if (newh < m->wh) + newy = m->wy + (m->wh - (newh + 2 * c->bw)) / 2; + + resize(c, newx, newy, neww, newh, 0); + } +} + +void motionnotify(XEvent *e) { + unsigned int i, x; + static Monitor *mon = NULL; + Monitor *m; + XMotionEvent *ev = &e->xmotion; + + if (ev->window == selmon->barwin) { + i = x = 0; + do + x += TEXTW(tags[i]); + while (ev->x >= x && ++i < LENGTH(tags)); + if (i < LENGTH(tags)) { + if ((i + 1) != selmon->previewshow && !(selmon->tagset[selmon->seltags] & 1 << i)) { + selmon->previewshow = i + 1; + showtagpreview(i); + } else if (selmon->tagset[selmon->seltags] & 1 << i) { + selmon->previewshow = 0; + showtagpreview(0); + } + } else if (selmon->previewshow != 0) { + selmon->previewshow = 0; + showtagpreview(0); + } + } else if (selmon->previewshow != 0) { + selmon->previewshow = 0; + showtagpreview(0); + } + + if (ev->window != root) + return; + if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) { + unfocus(selmon->sel, 1); + selmon = m; + focus(NULL); + } + mon = m; +} + +void +updateicon(Client *c) +{ + freeicon(c); + c->icon = geticonprop(c->win, &c->icw, &c->ich); +} + +void +moveorplace(const Arg *arg) { + if ((!selmon->lt[selmon->sellt]->arrange || (selmon->sel && selmon->sel->isfloating))) + movemouse(arg); + else + placemouse(arg); +} + +void movemouse(const Arg *arg) { + int x, y, ocx, ocy, nx, ny; + Client *c; + Monitor *m; + XEvent ev; + Time lasttime = 0; + + if (!(c = selmon->sel)) + return; + if (c->isfullscreen) /* no support moving fullscreen windows by mouse */ + return; + restack(selmon); + ocx = c->x; + ocy = c->y; + if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, + None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess) + return; + if (!getrootptr(&x, &y)) + return; + do { + XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); + switch (ev.type) { + case ConfigureRequest: + case Expose: + case MapRequest: + handler[ev.type](&ev); + break; + case MotionNotify: + if ((ev.xmotion.time - lasttime) <= (1000 / 60)) + continue; + lasttime = ev.xmotion.time; + + nx = ocx + (ev.xmotion.x - x); + ny = ocy + (ev.xmotion.y - y); + if (abs(selmon->wx - nx) < snap) + nx = selmon->wx; + else if (abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap) + nx = selmon->wx + selmon->ww - WIDTH(c); + if (abs(selmon->wy - ny) < snap) + ny = selmon->wy; + else if (abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap) + ny = selmon->wy + selmon->wh - HEIGHT(c); + if (!c->isfloating && selmon->lt[selmon->sellt]->arrange && + (abs(nx - c->x) > snap || abs(ny - c->y) > snap)) + togglefloating(NULL); + if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) + resize(c, nx, ny, c->w, c->h, 1); + break; + } + } while (ev.type != ButtonRelease); + XUngrabPointer(dpy, CurrentTime); + if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { + sendmon(c, m); + selmon = m; + focus(NULL); + } +} + +Client *nexttiled(Client *c) { + for (; c && (c->isfloating || (!ISVISIBLE(c) || HIDDEN(c))); c = c->next) + ; + return c; +} + +void +placemouse(const Arg *arg) +{ + int x, y, px, py, ocx, ocy, nx = -9999, ny = -9999, freemove = 0; + Client *c, *r = NULL, *at, *prevr; + Monitor *m; + XEvent ev; + XWindowAttributes wa; + Time lasttime = 0; + int attachmode, prevattachmode; + attachmode = prevattachmode = -1; + + if (!(c = selmon->sel) || !c->mon->lt[c->mon->sellt]->arrange) /* no support for placemouse when floating layout is used */ + return; + if (c->isfullscreen) /* no support placing fullscreen windows by mouse */ + return; + restack(selmon); + prevr = c; + if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, + None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess) + return; + + c->isfloating = 0; + c->beingmoved = 1; + + XGetWindowAttributes(dpy, c->win, &wa); + ocx = wa.x; + ocy = wa.y; + + if (arg->i == 2) // warp cursor to client center + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, WIDTH(c) / 2, HEIGHT(c) / 2); + + if (!getrootptr(&x, &y)) + return; + + do { + XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); + switch (ev.type) { + case ConfigureRequest: + case Expose: + case MapRequest: + handler[ev.type](&ev); + break; + case MotionNotify: + if ((ev.xmotion.time - lasttime) <= (1000 / 60)) + continue; + lasttime = ev.xmotion.time; + + nx = ocx + (ev.xmotion.x - x); + ny = ocy + (ev.xmotion.y - y); + + if (!freemove && (abs(nx - ocx) > snap || abs(ny - ocy) > snap)) + freemove = 1; + + if (freemove) + XMoveWindow(dpy, c->win, nx, ny); + + if ((m = recttomon(ev.xmotion.x, ev.xmotion.y, 1, 1)) && m != selmon) + selmon = m; + + if (arg->i == 1) { // tiled position is relative to the client window center point + px = nx + wa.width / 2; + py = ny + wa.height / 2; + } else { // tiled position is relative to the mouse cursor + px = ev.xmotion.x; + py = ev.xmotion.y; + } + + r = recttoclient(px, py, 1, 1); + + if (!r || r == c) + break; + + attachmode = 0; // below + if (((float)(r->y + r->h - py) / r->h) > ((float)(r->x + r->w - px) / r->w)) { + if (abs(r->y - py) < r->h / 2) + attachmode = 1; // above + } else if (abs(r->x - px) < r->w / 2) + attachmode = 1; // above + + if ((r && r != prevr) || (attachmode != prevattachmode)) { + detachstack(c); + detach(c); + if (c->mon != r->mon) { + arrangemon(c->mon); + c->tags = r->mon->tagset[r->mon->seltags]; + } + + c->mon = r->mon; + r->mon->sel = r; + + if (attachmode) { + if (r == r->mon->clients) + attach(c); + else { + for (at = r->mon->clients; at->next != r; at = at->next); + c->next = at->next; + at->next = c; + } + } else { + c->next = r->next; + r->next = c; + } + + attachstack(c); + arrangemon(r->mon); + prevr = r; + prevattachmode = attachmode; + } + break; + } + } while (ev.type != ButtonRelease); + XUngrabPointer(dpy, CurrentTime); + + if ((m = recttomon(ev.xmotion.x, ev.xmotion.y, 1, 1)) && m != c->mon) { + detach(c); + detachstack(c); + arrangemon(c->mon); + c->mon = m; + c->tags = m->tagset[m->seltags]; + attach(c); + attachstack(c); + selmon = m; + } + + focus(c); + c->beingmoved = 0; + + if (nx != -9999) + resize(c, nx, ny, c->w, c->h, 0); + arrangemon(c->mon); +} + +void pop(Client *c) { + detach(c); + attach(c); + focus(c); + arrange(c->mon); +} + +void propertynotify(XEvent *e) { + Client *c; + Window trans; + XPropertyEvent *ev = &e->xproperty; + + if ((c = wintosystrayicon(ev->window))) { + if (ev->atom == XA_WM_NORMAL_HINTS) { + updatesizehints(c); + updatesystrayicongeom(c, c->w, c->h); + } else + updatesystrayiconstate(c, ev); + resizebarwin(selmon); + updatesystray(); + } + if ((ev->window == root) && (ev->atom == XA_WM_NAME)) + updatestatus(); + else if (ev->state == PropertyDelete) + return; /* ignore */ + else if ((c = wintoclient(ev->window))) { + switch (ev->atom) { + default: + break; + case XA_WM_TRANSIENT_FOR: + if (!c->isfloating && (XGetTransientForHint(dpy, c->win, &trans)) && + (c->isfloating = (wintoclient(trans)) != NULL)) + arrange(c->mon); + break; + case XA_WM_NORMAL_HINTS: + c->hintsvalid = 0; + break; + case XA_WM_HINTS: + updatewmhints(c); + drawbars(); + drawtabs(); + break; + } + if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { + updatetitle(c); + if (c == c->mon->sel) + drawbar(c->mon); + drawtab(c->mon); + } + + else if (ev->atom == netatom[NetWMIcon]) { + updateicon(c); + if (c == c->mon->sel) + drawbar(c->mon); + } + + if (ev->atom == netatom[NetWMWindowType]) + updatewindowtype(c); + } +} + +void restart(const Arg *arg) { + running = 0; +} + +Client * +recttoclient(int x, int y, int w, int h) +{ + Client *c, *r = NULL; + int a, area = 0; + + for (c = nexttiled(selmon->clients); c; c = nexttiled(c->next)) { + if ((a = INTERSECTC(x, y, w, h, c)) > area) { + area = a; + r = c; + } + } + return r; +} + + +Monitor *recttomon(int x, int y, int w, int h) { + Monitor *m, *r = selmon; + int a, area = 0; + + for (m = mons; m; m = m->next) + if ((a = INTERSECT(x, y, w, h, m)) > area) { + area = a; + r = m; + } + return r; +} + +void removesystrayicon(Client *i) { + Client **ii; + + if (!showsystray || !i) + return; + for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next) + ; + if (ii) + *ii = i->next; + free(i); +} + +void resize(Client *c, int x, int y, int w, int h, int interact) { + if (applysizehints(c, &x, &y, &w, &h, interact)) + resizeclient(c, x, y, w, h); +} + +void resizebarwin(Monitor *m) { + unsigned int w =floatbar? m->ww - 2 * m->gappov:m->ww; + if (showsystray && m == systraytomon(m)) + w -= getsystraywidth(); + if(floatbar){ + XMoveResizeWindow(dpy, m->barwin, m->wx + m->gappov, m->by, w, bh); + }else{ + XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh); + } +} + +void resizeclient(Client *c, int x, int y, int w, int h) { + XWindowChanges wc; + + c->oldx = c->x; + c->x = wc.x = x; + c->oldy = c->y; + c->y = wc.y = y; + c->oldw = c->w; + c->w = wc.width = w; + c->oldh = c->h; + c->h = wc.height = h; + + if (c->beingmoved) + return; + + wc.border_width = c->bw; + XConfigureWindow(dpy, c->win, CWX | CWY | CWWidth | CWHeight | CWBorderWidth, + &wc); + configure(c); + XSync(dpy, False); +} + +void resizemouse(const Arg *arg) { + int ocx, ocy, nw, nh; + Client *c; + Monitor *m; + XEvent ev; + Time lasttime = 0; + + if (!(c = selmon->sel)) + return; + if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */ + return; + restack(selmon); + ocx = c->x; + ocy = c->y; + if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, + None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess) + return; + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, + c->h + c->bw - 1); + do { + XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); + switch (ev.type) { + case ConfigureRequest: + case Expose: + case MapRequest: + handler[ev.type](&ev); + break; + case MotionNotify: + if ((ev.xmotion.time - lasttime) <= (1000 / 60)) + continue; + lasttime = ev.xmotion.time; + + nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1); + nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1); + if (c->mon->wx + nw >= selmon->wx && + c->mon->wx + nw <= selmon->wx + selmon->ww && + c->mon->wy + nh >= selmon->wy && + c->mon->wy + nh <= selmon->wy + selmon->wh) { + if (!c->isfloating && selmon->lt[selmon->sellt]->arrange && + (abs(nw - c->w) > snap || abs(nh - c->h) > snap)) + togglefloating(NULL); + } + if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) + resize(c, c->x, c->y, nw, nh, 1); + break; + } + } while (ev.type != ButtonRelease); + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, + c->h + c->bw - 1); + XUngrabPointer(dpy, CurrentTime); + while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)) + ; + if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { + sendmon(c, m); + selmon = m; + focus(NULL); + } +} + +void resizerequest(XEvent *e) { + XResizeRequestEvent *ev = &e->xresizerequest; + Client *i; + + if ((i = wintosystrayicon(ev->window))) { + updatesystrayicongeom(i, ev->width, ev->height); + resizebarwin(selmon); + updatesystray(); + } +} + +void restack(Monitor *m) { + Client *c; + XEvent ev; + XWindowChanges wc; + + drawbar(m); + drawtab(m); + if (!m->sel) + return; + if (m->sel->isfloating || !m->lt[m->sellt]->arrange) + XRaiseWindow(dpy, m->sel->win); + if (m->lt[m->sellt]->arrange) { + wc.stack_mode = Below; + wc.sibling = m->barwin; + for (c = m->stack; c; c = c->snext) + if (!c->isfloating && ISVISIBLE(c)) { + XConfigureWindow(dpy, c->win, CWSibling | CWStackMode, &wc); + wc.sibling = c->win; + } + } + XSync(dpy, False); + while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)) + ; +} + +void run(void) { + XEvent ev; + /* main event loop */ + XSync(dpy, False); + while (running && !XNextEvent(dpy, &ev)) + if (handler[ev.type]) + handler[ev.type](&ev); /* call handler */ +} + +void scan(void) { + unsigned int i, num; + Window d1, d2, *wins = NULL; + XWindowAttributes wa; + + if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) { + for (i = 0; i < num; i++) { + if (!XGetWindowAttributes(dpy, wins[i], &wa) || wa.override_redirect || + XGetTransientForHint(dpy, wins[i], &d1)) + continue; + if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState) + manage(wins[i], &wa); + } + for (i = 0; i < num; i++) { /* now the transients */ + if (!XGetWindowAttributes(dpy, wins[i], &wa)) + continue; + if (XGetTransientForHint(dpy, wins[i], &d1) && + (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)) + manage(wins[i], &wa); + } + if (wins) + XFree(wins); + } +} + +void sendmon(Client *c, Monitor *m) { + if (c->mon == m) + return; + unfocus(c, 1); + detach(c); + detachstack(c); + c->mon = m; + c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ + attach(c); + attachstack(c); + setclienttagprop(c); + focus(NULL); + arrange(NULL); +} + +void setborderpx(const Arg *arg) { + Client *c; + int prev_borderpx = selmon->borderpx; + + if (arg->i == 0) + selmon->borderpx = borderpx; + else if (selmon->borderpx + arg->i < 0) + selmon->borderpx = 0; + else + selmon->borderpx += arg->i; + + for (c = selmon->clients; c; c = c->next) { + if (c->bw + arg->i < 0) + c->bw = selmon->borderpx = 0; + else + c->bw = selmon->borderpx; + if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) { + if (arg->i != 0 && prev_borderpx + arg->i >= 0) + resize(c, c->x, c->y, c->w - (arg->i * 2), c->h - (arg->i * 2), 0); + else if (arg->i != 0) + resizeclient(c, c->x, c->y, c->w, c->h); + else if (prev_borderpx > borderpx) + resize(c, c->x, c->y, c->w + 2 * (prev_borderpx - borderpx), + c->h + 2 * (prev_borderpx - borderpx), 0); + else if (prev_borderpx < borderpx) + resize(c, c->x, c->y, c->w - 2 * (borderpx - prev_borderpx), + c->h - 2 * (borderpx - prev_borderpx), 0); + } + } + arrange(selmon); +} + +void setclientstate(Client *c, long state) { + long data[] = {state, None}; + + XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32, + PropModeReplace, (unsigned char *)data, 2); +} + +void +setcurrentdesktop(void){ + long data[] = { 0 }; + XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1); +} +void setdesktopnames(void){ + XTextProperty text; + Xutf8TextListToTextProperty(dpy, tags, TAGSLENGTH, XUTF8StringStyle, &text); + XSetTextProperty(dpy, root, &text, netatom[NetDesktopNames]); +} + +int sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, + long d3, long d4) { + int n; + Atom *protocols, mt; + int exists = 0; + XEvent ev; + + if (proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) { + mt = wmatom[WMProtocols]; + if (XGetWMProtocols(dpy, w, &protocols, &n)) { + while (!exists && n--) + exists = protocols[n] == proto; + XFree(protocols); + } + } else { + exists = True; + mt = proto; + } + if (exists) { + ev.type = ClientMessage; + ev.xclient.window = w; + ev.xclient.message_type = mt; + ev.xclient.format = 32; + ev.xclient.data.l[0] = d0; + ev.xclient.data.l[1] = d1; + ev.xclient.data.l[2] = d2; + ev.xclient.data.l[3] = d3; + ev.xclient.data.l[4] = d4; + XSendEvent(dpy, w, False, mask, &ev); + } + return exists; +} + +void +setnumdesktops(void){ + long data[] = { TAGSLENGTH }; + XChangeProperty(dpy, root, netatom[NetNumberOfDesktops], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1); +} + +void setfocus(Client *c) { + if (!c->neverfocus) { + XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); + XChangeProperty(dpy, root, netatom[NetActiveWindow], XA_WINDOW, 32, + PropModeReplace, (unsigned char *)&(c->win), 1); + } + sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], + CurrentTime, 0, 0, 0); +} + +void setfullscreen(Client *c, int fullscreen) { + if (fullscreen && !c->isfullscreen) { + XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, + PropModeReplace, (unsigned char *)&netatom[NetWMFullscreen], + 1); + c->isfullscreen = 1; + c->oldstate = c->isfloating; + c->oldbw = c->bw; + c->bw = 0; + c->isfloating = 1; + resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh); + XRaiseWindow(dpy, c->win); + } else if (!fullscreen && c->isfullscreen) { + XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, + PropModeReplace, (unsigned char *)0, 0); + c->isfullscreen = 0; + c->isfloating = c->oldstate; + c->bw = c->oldbw; + c->x = c->oldx; + c->y = c->oldy; + c->w = c->oldw; + c->h = c->oldh; + resizeclient(c, c->x, c->y, c->w, c->h); + arrange(c->mon); + } +} + +void setlayout(const Arg *arg) { + if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1; + if (arg && arg->v) + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v; + strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, + sizeof selmon->ltsymbol); + if (selmon->sel) + arrange(selmon); + else + drawbar(selmon); +} + +void setcfact(const Arg *arg) { + float f; + Client *c; + + c = selmon->sel; + + if (!arg || !c || !selmon->lt[selmon->sellt]->arrange) + return; + if (!arg->f) + f = 1.0; + else if (arg->f > 4.0) // set fact absolutely + f = arg->f - 4.0; + else + f = arg->f + c->cfact; + if (f < 0.25) + f = 0.25; + else if (f > 4.0) + f = 4.0; + c->cfact = f; + arrange(selmon); +} + +/* arg > 1.0 will set mfact absolutely */ +void setmfact(const Arg *arg) { + float f; + + if (!arg || !selmon->lt[selmon->sellt]->arrange) + return; + f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; + if (f < 0.05 || f > 0.95) + return; + selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f; + arrange(selmon); +} + +void setup(void) { + int i; + XSetWindowAttributes wa; + Atom utf8string; + + /* clean up any zombies immediately */ + sigchld(0); + + /* init screen */ + screen = DefaultScreen(dpy); + sw = DisplayWidth(dpy, screen); + sh = DisplayHeight(dpy, screen); + root = RootWindow(dpy, screen); + drw = drw_create(dpy, screen, root, sw, sh); + if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) + die("no fonts could be loaded."); + lrpad = drw->fonts->h; + bh = drw->fonts->h + 2 + vertpadbar + borderpx * 2; + th = vertpadtab; + // bh_n = vertpadtab; + updategeom(); + /* init atoms */ + utf8string = XInternAtom(dpy, "UTF8_STRING", False); + wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); + wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False); + wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); + netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); + netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); + netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False); + netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False); + netatom[NetSystemTrayOrientation] = + XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False); + netatom[NetSystemTrayOrientationHorz] = + XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", False); + netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); + netatom[NetWMIcon] = XInternAtom(dpy, "_NET_WM_ICON", False); + netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); + netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False); + netatom[NetWMFullscreen] = + XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); + netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); + netatom[NetWMWindowTypeDialog] = + XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); + netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); + xatom[Manager] = XInternAtom(dpy, "MANAGER", False); + xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False); + xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False); + netatom[NetDesktopViewport] = XInternAtom(dpy, "_NET_DESKTOP_VIEWPORT", False); + netatom[NetNumberOfDesktops] = XInternAtom(dpy, "_NET_NUMBER_OF_DESKTOPS", False); + netatom[NetCurrentDesktop] = XInternAtom(dpy, "_NET_CURRENT_DESKTOP", False); + netatom[NetDesktopNames] = XInternAtom(dpy, "_NET_DESKTOP_NAMES", False); + netatom[NetClientInfo] = XInternAtom(dpy, "_NET_CLIENT_INFO", False); + /* init cursors */ + cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); + cursor[CurResize] = drw_cur_create(drw, XC_sizing); + cursor[CurMove] = drw_cur_create(drw, XC_fleur); + cursor[CurResizeHorzArrow] = drw_cur_create(drw, XC_sb_h_double_arrow); + cursor[CurResizeVertArrow] = drw_cur_create(drw, XC_sb_v_double_arrow); + /* init appearance */ + scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *)); + scheme[LENGTH(colors)] = drw_scm_create(drw, colors[0], 3); + for (i = 0; i < LENGTH(colors); i++) + scheme[i] = drw_scm_create(drw, colors[i], 3); + drw_clr_create(drw, &clrborder, col_borderbar); + /* init system tray */ + updatesystray(); + /* init bars */ + updatebars(); + updatestatus(); + updatebarpos(selmon); + updatepreview(); + /* supporting window for NetWMCheck */ + wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0); + XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32, + PropModeReplace, (unsigned char *)&wmcheckwin, 1); + XChangeProperty(dpy, wmcheckwin, netatom[NetWMName], utf8string, 8, + PropModeReplace, (unsigned char *)"dwm", 3); + XChangeProperty(dpy, root, netatom[NetWMCheck], XA_WINDOW, 32, + PropModeReplace, (unsigned char *)&wmcheckwin, 1); + /* EWMH support per view */ + XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32, + PropModeReplace, (unsigned char *)netatom, NetLast); + setnumdesktops(); + setcurrentdesktop(); + setdesktopnames(); + setviewport(); + XDeleteProperty(dpy, root, netatom[NetClientList]); + XDeleteProperty(dpy, root, netatom[NetClientInfo]); + /* select events */ + wa.cursor = cursor[CurNormal]->cursor; + wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask | + ButtonPressMask | PointerMotionMask | EnterWindowMask | + LeaveWindowMask | StructureNotifyMask | PropertyChangeMask; + XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa); + XSelectInput(dpy, root, wa.event_mask); + grabkeys(); + focus(NULL); +} +void +setviewport(void){ + long data[] = { 0, 0 }; + XChangeProperty(dpy, root, netatom[NetDesktopViewport], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 2); +} + +void seturgent(Client *c, int urg) { + XWMHints *wmh; + + c->isurgent = urg; + if (!(wmh = XGetWMHints(dpy, c->win))) + return; + wmh->flags = urg ? (wmh->flags | XUrgencyHint) : (wmh->flags & ~XUrgencyHint); + XSetWMHints(dpy, c->win, wmh); + XFree(wmh); +} + +void +show(Client *c) +{ + if (!c || !HIDDEN(c)) + return; + + XMapWindow(dpy, c->win); + setclientstate(c, NormalState); + arrange(c->mon); +} + +void showhide(Client *c) { + if (!c) + return; + if (ISVISIBLE(c)) { + /* show clients top down */ + XMoveWindow(dpy, c->win, c->x, c->y); + if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && + !c->isfullscreen) + resize(c, c->x, c->y, c->w, c->h, 0); + showhide(c->snext); + } else { + /* hide clients bottom up */ + showhide(c->snext); + XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y); + } +} + +void +showtagpreview(int tag) +{ + if (!selmon->previewshow || !tag_preview ) { + XUnmapWindow(dpy, selmon->tagwin); + return; + } + + if (selmon->tagmap[tag]) { + XSetWindowBackgroundPixmap(dpy, selmon->tagwin, selmon->tagmap[tag]); + XCopyArea(dpy, selmon->tagmap[tag], selmon->tagwin, drw->gc, 0, 0, selmon->mw / scalepreview, selmon->mh / scalepreview, 0, 0); + XSync(dpy, False); + XMapWindow(dpy, selmon->tagwin); + } else + XUnmapWindow(dpy, selmon->tagwin); +} + + +void sigchld(int unused) { + if (signal(SIGCHLD, sigchld) == SIG_ERR) + die("can't install SIGCHLD handler:"); + while (0 < waitpid(-1, NULL, WNOHANG)) + ; +} + + +void spawn(const Arg *arg) { + if (fork() == 0) { + if (dpy) + close(ConnectionNumber(dpy)); + setsid(); + execvp(((char **)arg->v)[0], (char **)arg->v); + die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]); + } +} + +void +setclienttagprop(Client *c) +{ + long data[] = { (long) c->tags, (long) c->mon->num }; + XChangeProperty(dpy, c->win, netatom[NetClientInfo], XA_CARDINAL, 32, + PropModeReplace, (unsigned char *) data, 2); +} + + +void switchtag(void) { + int i; + unsigned int occ = 0; + Client *c; + Imlib_Image image; + + for (c = selmon->clients; c; c = c->next) + occ |= c->tags; + for (i = 0; i < LENGTH(tags); i++) { + if (selmon->tagset[selmon->seltags] & 1 << i) { + if (selmon->tagmap[i] != 0) { + XFreePixmap(dpy, selmon->tagmap[i]); + selmon->tagmap[i] = 0; + } + if (occ & 1 << i && tag_preview) { + image = imlib_create_image(sw, sh); + imlib_context_set_image(image); + imlib_context_set_display(dpy); + imlib_context_set_visual(DefaultVisual(dpy, screen)); + imlib_context_set_drawable(RootWindow(dpy, screen)); + imlib_copy_drawable_to_image(0, selmon->mx, selmon->my, selmon->mw ,selmon->mh, 0, 0, 1); + selmon->tagmap[i] = XCreatePixmap(dpy, selmon->tagwin, selmon->mw / scalepreview, selmon->mh / scalepreview, DefaultDepth(dpy, screen)); + imlib_context_set_drawable(selmon->tagmap[i]); + imlib_render_image_part_on_drawable_at_size(0, 0, selmon->mw, selmon->mh, 0, 0, selmon->mw / scalepreview, selmon->mh / scalepreview); + imlib_free_image(); + } + } + } +} + +void +tabmode(const Arg *arg) +{ + if(arg && arg->i >= 0) + selmon->showtab = arg->ui % showtab_nmodes; + else + selmon->showtab = (selmon->showtab + 1 ) % showtab_nmodes; + arrange(selmon); +} + +void tag(const Arg *arg) { + Client *c; + if (selmon->sel && arg->ui & TAGMASK) { + c = selmon->sel; + selmon->sel->tags = arg->ui & TAGMASK; + setclienttagprop(c); + focus(NULL); + arrange(selmon); + } +} + +void tagmon(const Arg *arg) { + if (!selmon->sel || !mons->next) + return; + sendmon(selmon->sel, dirtomon(arg->i)); +} + +void togglebar(const Arg *arg) { + selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar; + updatebarpos(selmon); + resizebarwin(selmon); + if (showsystray) { + XWindowChanges wc; + if (!selmon->showbar) + wc.y = -bh; + else if (selmon->showbar) { + wc.y = selmon->gappoh; + if (!selmon->topbar) + wc.y = selmon->mh - bh + selmon->gappoh; + } + XConfigureWindow(dpy, systray->win, CWY, &wc); + } + arrange(selmon); +} + +void togglefloating(const Arg *arg) { + if (!selmon->sel) + return; + if (selmon->sel->isfullscreen) /* no support for fullscreen windows */ + return; + selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; + if (selmon->sel->isfloating) + resize(selmon->sel, selmon->sel->x, selmon->sel->y, selmon->sel->w, + selmon->sel->h, 0); + arrange(selmon); +} + +void togglefullscr(const Arg *arg) { + if (selmon->sel) + setfullscreen(selmon->sel, !selmon->sel->isfullscreen); +} + +void toggletag(const Arg *arg) { + unsigned int newtags; + + if (!selmon->sel) + return; + newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); + if (newtags) { + selmon->sel->tags = newtags; + setclienttagprop(selmon->sel); + focus(NULL); + arrange(selmon); + } + updatecurrentdesktop(); +} + +void toggleview(const Arg *arg) { + unsigned int newtagset = + selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); + int i; + + + if (newtagset) { + switchtag(); + selmon->tagset[selmon->seltags] = newtagset; + + if (newtagset == ~0) { + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = 0; + } + + /* test if the user did not select the same tag */ + if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) { + selmon->pertag->prevtag = selmon->pertag->curtag; + for (i = 0; !(newtagset & 1 << i); i++) ; + selmon->pertag->curtag = i + 1; + } + + /* apply settings for this view */ + selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; + selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; + selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; + + if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) + togglebar(NULL); + + + focus(NULL); + arrange(selmon); + } + updatecurrentdesktop(); +} + +void hidewin(const Arg *arg) { + if (!selmon->sel) + return; + Client *c = (Client*)selmon->sel; + hide(c); + hiddenWinStack[++hiddenWinStackTop] = c; +} + +void restorewin(const Arg *arg) { + int i = hiddenWinStackTop; + while (i > -1) { + if (HIDDEN(hiddenWinStack[i]) && hiddenWinStack[i]->tags == selmon->tagset[selmon->seltags]) { + show(hiddenWinStack[i]); + focus(hiddenWinStack[i]); + restack(selmon); + for (int j = i; j < hiddenWinStackTop; ++j) { + hiddenWinStack[j] = hiddenWinStack[j + 1]; + } + --hiddenWinStackTop; + return; + } + --i; + } +} + +void unfocus(Client *c, int setfocus) { + if (!c) + return; + grabbuttons(c, 0); + XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel); + if (setfocus) { + XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); + XDeleteProperty(dpy, root, netatom[NetActiveWindow]); + } +} + +void unmanage(Client *c, int destroyed) { + Monitor *m = c->mon; + XWindowChanges wc; + + detach(c); + detachstack(c); + freeicon(c); + + if (!destroyed) { + wc.border_width = c->oldbw; + XGrabServer(dpy); /* avoid race conditions */ + XSetErrorHandler(xerrordummy); + XSelectInput(dpy, c->win, NoEventMask); + XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */ + XUngrabButton(dpy, AnyButton, AnyModifier, c->win); + setclientstate(c, WithdrawnState); + XSync(dpy, False); + XSetErrorHandler(xerror); + XUngrabServer(dpy); + } + free(c); + focus(NULL); + updateclientlist(); + arrange(m); +} + +void unmapnotify(XEvent *e) { + Client *c; + XUnmapEvent *ev = &e->xunmap; + + if ((c = wintoclient(ev->window))) { + if (ev->send_event) + setclientstate(c, WithdrawnState); + else + unmanage(c, 0); + } else if ((c = wintosystrayicon(ev->window))) { + /* KLUDGE! sometimes icons occasionally unmap their windows, but do + * _not_ destroy them. We map those windows back */ + XMapRaised(dpy, c->win); + updatesystray(); + } +} + +void updatebars(void) { + unsigned int w; + Monitor *m; + XSetWindowAttributes wa = {.override_redirect = True, + .background_pixmap = ParentRelative, + .event_mask = ButtonPressMask|ExposureMask|PointerMotionMask}; + + XClassHint ch = {"dwm", "dwm"}; + for (m = mons; m; m = m->next) { + if (m->barwin) + continue; + w = m->ww; + if (showsystray && m == systraytomon(m)) + w -= getsystraywidth(); + m->barwin = XCreateWindow( + dpy, root, m->wx + m->gappov, m->by, w - 2 * m->gappov, bh, 0, + DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), + CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); + XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); + if (showsystray && m == systraytomon(m)) + XMapRaised(dpy, systray->win); + XMapRaised(dpy, m->barwin); + m->tabwin = XCreateWindow(dpy, root, m->wx + m->gappov, m->ty, m->ww - 2 * m->gappov, th, 0, DefaultDepth(dpy, screen), + CopyFromParent, DefaultVisual(dpy, screen), + CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); + XDefineCursor(dpy, m->tabwin, cursor[CurNormal]->cursor); + XMapRaised(dpy, m->tabwin); + XSetClassHint(dpy, m->barwin, &ch); + } +} + +void +updatepreview(void) +{ + Monitor *m; + + XSetWindowAttributes wa = { + .override_redirect = True, + .background_pixmap = ParentRelative, + .event_mask = ButtonPressMask|ExposureMask + }; + for (m = mons; m; m = m->next) { + m->tagwin = XCreateWindow(dpy, root, m->wx, m->by + bh, m->mw / 4, m->mh / 4, 0, + DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), + CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); + XDefineCursor(dpy, m->tagwin, cursor[CurNormal]->cursor); + XMapRaised(dpy, m->tagwin); + XUnmapWindow(dpy, m->tagwin); + } +} + +void updatebarpos(Monitor *m) { + Client *c; + int nvis = 0; + + m->wy = m->my; + m->wh = m->mh; + + for(c = m->clients; c; c = c->next) { + if(ISVISIBLE(c)) ++nvis; + } + + if(m->showtab == showtab_always + || ((m->showtab == showtab_auto) && (nvis > 1) && (m->lt[m->sellt]->arrange == monocle))) { + m->topbar = !toptab; + m->wh -= th + ((m->topbar == toptab && m->showbar) ? 0 : m->gappoh) - m->gappoh; + m->ty = m->toptab ? m->wy + ((m->topbar && m->showbar) ? 0 : m->gappoh) : m->wy + m->wh - m->gappoh; + if ( m->toptab ) + m->wy += th + ((m->topbar && m->showbar) ? 0 : m->gappoh) - m->gappoh; + } else { + m->ty = -th - m->gappoh; + m->topbar = topbar; + } + if (m->showbar) { + if(floatbar){ + m->wh = m->wh - m->gappoh - bh; + m->by = m->topbar ? m->wy + m->gappoh : m->wy + m->wh; + }else{ + m->wh = m->wh - bh; + m->by = m->topbar ? m->wy : m->wy + m->wh; + } + if (m->topbar){ + m->wy = floatbar?bh+gappoh:bh; + } + } else + m->by = -bh - m->gappoh; +} + +void updateclientlist() { + Client *c; + Monitor *m; + + XDeleteProperty(dpy, root, netatom[NetClientList]); + for (m = mons; m; m = m->next) + for (c = m->clients; c; c = c->next) + XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, + PropModeAppend, (unsigned char *)&(c->win), 1); +} + +void updatecurrentdesktop(void){ + long rawdata[] = { selmon->tagset[selmon->seltags] }; + int i=0; + while(*rawdata >> (i+1)){ + i++; + } + long data[] = { i }; + XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1); +} + +int updategeom(void) { + int dirty = 0; + +#ifdef XINERAMA + if (XineramaIsActive(dpy)) { + int i, j, n, nn; + Client *c; + Monitor *m; + XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn); + XineramaScreenInfo *unique = NULL; + + for (n = 0, m = mons; m; m = m->next, n++) + ; + /* only consider unique geometries as separate screens */ + unique = ecalloc(nn, sizeof(XineramaScreenInfo)); + for (i = 0, j = 0; i < nn; i++) + if (isuniquegeom(unique, j, &info[i])) + memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo)); + XFree(info); + nn = j; + /* new monitors if nn > n */ + for (i = n; i < nn; i++) { + for (m = mons; m && m->next; m = m->next); + if (m) + m->next = createmon(); + else + mons = createmon(); + } + for (i = 0, m = mons; i < nn && m; m = m->next, i++) + if (i >= n + || unique[i].x_org != m->mx || unique[i].y_org != m->my + || unique[i].width != m->mw || unique[i].height != m->mh) + { + dirty = 1; + m->num = i; + m->mx = m->wx = unique[i].x_org; + m->my = m->wy = unique[i].y_org; + m->mw = m->ww = unique[i].width; + m->mh = m->wh = unique[i].height; + updatebarpos(m); + } + /* removed monitors if n > nn */ + for (i = nn; i < n; i++) { + for (m = mons; m && m->next; m = m->next); + while ((c = m->clients)) { + dirty = 1; + m->clients = c->next; + detachstack(c); + c->mon = mons; + attach(c); + attachstack(c); + } + if (m == selmon) + selmon = mons; + cleanupmon(m); + } + free(unique); + } else +#endif /* XINERAMA */ + { /* default monitor setup */ + if (!mons) + mons = createmon(); + if (mons->mw != sw || mons->mh != sh) { + dirty = 1; + mons->mw = mons->ww = sw; + mons->mh = mons->wh = sh; + updatebarpos(mons); + } + } + if (dirty) { + selmon = mons; + selmon = wintomon(root); + } + return dirty; +} + +void updatenumlockmask(void) { + unsigned int i, j; + XModifierKeymap *modmap; + + numlockmask = 0; + modmap = XGetModifierMapping(dpy); + for (i = 0; i < 8; i++) + for (j = 0; j < modmap->max_keypermod; j++) + if (modmap->modifiermap[i * modmap->max_keypermod + j] == + XKeysymToKeycode(dpy, XK_Num_Lock)) + numlockmask = (1 << i); + XFreeModifiermap(modmap); +} + +void updatesizehints(Client *c) { + long msize; + XSizeHints size; + + if (!XGetWMNormalHints(dpy, c->win, &size, &msize)) + /* size is uninitialized, ensure that size.flags aren't used */ + size.flags = PSize; + if (size.flags & PBaseSize) { + c->basew = size.base_width; + c->baseh = size.base_height; + } else if (size.flags & PMinSize) { + c->basew = size.min_width; + c->baseh = size.min_height; + } else + c->basew = c->baseh = 0; + if (size.flags & PResizeInc) { + c->incw = size.width_inc; + c->inch = size.height_inc; + } else + c->incw = c->inch = 0; + if (size.flags & PMaxSize) { + c->maxw = size.max_width; + c->maxh = size.max_height; + } else + c->maxw = c->maxh = 0; + if (size.flags & PMinSize) { + c->minw = size.min_width; + c->minh = size.min_height; + } else if (size.flags & PBaseSize) { + c->minw = size.base_width; + c->minh = size.base_height; + } else + c->minw = c->minh = 0; + if (size.flags & PAspect) { + c->mina = (float)size.min_aspect.y / size.min_aspect.x; + c->maxa = (float)size.max_aspect.x / size.max_aspect.y; + } else + c->maxa = c->mina = 0.0; + c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh); + c->hintsvalid = 1; +} + +void updatestatus(void) { + if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) + strcpy(stext, "dwm-" VERSION); + drawbar(selmon); + updatesystray(); +} + +void updatesystrayicongeom(Client *i, int w, int h) { + int rh = bh - vertpadbar; + if (i) { + i->h = rh; + if (w == h) + i->w = rh; + else if (h == rh) + i->w = w; + else + i->w = (int)((float)rh * ((float)w / (float)h)); + i->y = i->y + vertpadbar / 2; + applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False); + /* force icons into the systray dimensions if they don't want to */ + if (i->h > rh) { + if (i->w == i->h) + i->w = rh; + else + i->w = (int)((float)rh * ((float)i->w / (float)i->h)); + i->h = rh; + } + } +} + +void updatesystrayiconstate(Client *i, XPropertyEvent *ev) { + long flags; + int code = 0; + + if (!showsystray || !i || ev->atom != xatom[XembedInfo] || + !(flags = getatomprop(i, xatom[XembedInfo]))) + return; + + if (flags & XEMBED_MAPPED && !i->tags) { + i->tags = 1; + code = XEMBED_WINDOW_ACTIVATE; + XMapRaised(dpy, i->win); + setclientstate(i, NormalState); + } else if (!(flags & XEMBED_MAPPED) && i->tags) { + i->tags = 0; + code = XEMBED_WINDOW_DEACTIVATE; + XUnmapWindow(dpy, i->win); + setclientstate(i, WithdrawnState); + } else + return; + sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0, + systray->win, XEMBED_EMBEDDED_VERSION); +} + +void updatesystray(void) { + XSetWindowAttributes wa; + XWindowChanges wc; + Client *i; + Monitor *m = systraytomon(NULL); + unsigned int x = floatbar?m->mx + m->mw - m->gappov:m->mx + m->mw; + unsigned int w = 1; + + if (!showsystray) + return; + if (!systray) { + /* init systray */ + if (!(systray = (Systray *)calloc(1, sizeof(Systray)))) + die("fatal: could not malloc() %u bytes\n", sizeof(Systray)); + systray->win = XCreateSimpleWindow(dpy, root, x, m->by, w, bh, 0, 0, + scheme[SchemeSel][ColBg].pixel); + wa.event_mask = ButtonPressMask | ExposureMask; + wa.override_redirect = True; + wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; + XSelectInput(dpy, systray->win, SubstructureNotifyMask); + XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], + XA_CARDINAL, 32, PropModeReplace, + (unsigned char *)&netatom[NetSystemTrayOrientationHorz], 1); + XChangeWindowAttributes( + dpy, systray->win, CWEventMask | CWOverrideRedirect | CWBackPixel, &wa); + XMapRaised(dpy, systray->win); + XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime); + if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) { + sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, + netatom[NetSystemTray], systray->win, 0, 0); + XSync(dpy, False); + } else { + fprintf(stderr, "dwm: unable to obtain system tray.\n"); + free(systray); + systray = NULL; + return; + } + } + for (w = 0, i = systray->icons; i; i = i->next) { + /* make sure the background color stays the same */ + wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; + XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa); + XMapRaised(dpy, i->win); + w += systrayspacing; + i->x = w; + XMoveResizeWindow(dpy, i->win, i->x, vertpadbar / 2, i->w, i->h); + w += i->w; + if (i->mon != m) + i->mon = m; + } + w = w ? w + systrayspacing : 1; + x -= w; + XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh); + wc.x = x; + wc.y = m->by; + wc.width = w; + wc.height = bh; + wc.stack_mode = Above; + wc.sibling = m->barwin; + XConfigureWindow(dpy, systray->win, + CWX | CWY | CWWidth | CWHeight | CWSibling | CWStackMode, + &wc); + XMapWindow(dpy, systray->win); + XMapSubwindows(dpy, systray->win); + /* redraw background */ + XSetForeground(dpy, drw->gc, scheme[SchemeNorm][ColBg].pixel); + XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh); + XSync(dpy, False); +} + +void updatetitle(Client *c) { + if (!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name)) + gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name); + if (c->name[0] == '\0') /* hack to mark broken clients */ + strcpy(c->name, broken); +} + +void updatewindowtype(Client *c) { + Atom state = getatomprop(c, netatom[NetWMState]); + Atom wtype = getatomprop(c, netatom[NetWMWindowType]); + + if (state == netatom[NetWMFullscreen]) + setfullscreen(c, 1); + if (wtype == netatom[NetWMWindowTypeDialog]) { + c->iscentered = 1; + c->isfloating = 1; + } +} + +void updatewmhints(Client *c) { + XWMHints *wmh; + + if ((wmh = XGetWMHints(dpy, c->win))) { + if (c == selmon->sel && wmh->flags & XUrgencyHint) { + wmh->flags &= ~XUrgencyHint; + XSetWMHints(dpy, c->win, wmh); + } else + c->isurgent = (wmh->flags & XUrgencyHint) ? 1 : 0; + if (wmh->flags & InputHint) + c->neverfocus = !wmh->input; + else + c->neverfocus = 0; + XFree(wmh); + } +} + +void view(const Arg *arg) { + int i; + unsigned int tmptag; + + if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) + return; + switchtag(); + selmon->seltags ^= 1; /* toggle sel tagset */ + if (arg->ui & TAGMASK) { + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; + + if (arg->ui == ~0) + selmon->pertag->curtag = 0; + else { + for (i = 0; !(arg->ui & 1 << i); i++) ; + selmon->pertag->curtag = i + 1; + } + } else { + tmptag = selmon->pertag->prevtag; + selmon->pertag->prevtag = selmon->pertag->curtag; + selmon->pertag->curtag = tmptag; + } + + selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; + selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; + selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; + selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; + selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; + + if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag]) + togglebar(NULL); + focus(NULL); + arrange(selmon); + updatecurrentdesktop(); +} + +Client *wintoclient(Window w) { + Client *c; + Monitor *m; + + for (m = mons; m; m = m->next) + for (c = m->clients; c; c = c->next) + if (c->win == w) + return c; + return NULL; +} + +Client *wintosystrayicon(Window w) { + Client *i = NULL; + + if (!showsystray || !w) + return i; + for (i = systray->icons; i && i->win != w; i = i->next) + ; + return i; +} + +Monitor *wintomon(Window w) { + int x, y; + Client *c; + Monitor *m; + + if (w == root && getrootptr(&x, &y)) + return recttomon(x, y, 1, 1); + for (m = mons; m; m = m->next) + if (w == m->barwin || w == m->tabwin) + return m; + if ((c = wintoclient(w))) + return c->mon; + return selmon; +} + +/* There's no way to check accesses to destroyed windows, thus those cases are + * ignored (especially on UnmapNotify's). Other types of errors call Xlibs + * default error handler, which may call exit. */ +int xerror(Display *dpy, XErrorEvent *ee) { + if (ee->error_code == BadWindow || + (ee->request_code == X_SetInputFocus && ee->error_code == BadMatch) || + (ee->request_code == X_PolyText8 && ee->error_code == BadDrawable) || + (ee->request_code == X_PolyFillRectangle && + ee->error_code == BadDrawable) || + (ee->request_code == X_PolySegment && ee->error_code == BadDrawable) || + (ee->request_code == X_ConfigureWindow && ee->error_code == BadMatch) || + (ee->request_code == X_GrabButton && ee->error_code == BadAccess) || + (ee->request_code == X_GrabKey && ee->error_code == BadAccess) || + (ee->request_code == X_CopyArea && ee->error_code == BadDrawable)) + return 0; + fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n", + ee->request_code, ee->error_code); + return xerrorxlib(dpy, ee); /* may call exit */ +} + +int xerrordummy(Display *dpy, XErrorEvent *ee) { return 0; } + +/* Startup Error handler to check if another window manager + * is already running. */ +int xerrorstart(Display *dpy, XErrorEvent *ee) { + die("dwm: another window manager is already running"); + return -1; +} + +Monitor *systraytomon(Monitor *m) { + Monitor *t; + int i, n; + if (!systraypinning) { + if (!m) + return selmon; + return m == selmon ? m : NULL; + } + for (n = 1, t = mons; t && t->next; n++, t = t->next) + ; + for (i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) + ; + if (systraypinningfailfirst && n < systraypinning) + return mons; + return t; +} + +void zoom(const Arg *arg) { + Client *c = selmon->sel; + + if (!selmon->lt[selmon->sellt]->arrange || !c || c->isfloating) + return; + if (c == nexttiled(selmon->clients) && !(c = nexttiled(c->next))) + return; + pop(c); +} + +int main(int argc, char *argv[]) { + if (argc == 2 && !strcmp("-v", argv[1])) + die("dwm-" VERSION); + else if (argc != 1 && strcmp("-s", argv[1])) + die("usage: dwm [-v]"); + if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) + fputs("warning: no locale support\n", stderr); + if (!(dpy = XOpenDisplay(NULL))) + die("dwm: cannot open display"); + if (argc > 1 && !strcmp("-s", argv[1])) { + XStoreName(dpy, RootWindow(dpy, DefaultScreen(dpy)), argv[2]); + XCloseDisplay(dpy); + return 0; + } + checkotherwm(); + setup(); +#ifdef __OpenBSD__ + if (pledge("stdio rpath proc exec", NULL) == -1) + die("pledge"); +#endif /* __OpenBSD__ */ + scan(); + run(); + cleanup(); + XCloseDisplay(dpy); + return EXIT_SUCCESS; +} diff --git a/t480s/dwm/dwm/dwm.o b/t480s/dwm/dwm/dwm.o new file mode 100644 index 0000000000000000000000000000000000000000..3cb5d0c649f3ba549a39a19929847a9cc6694eda GIT binary patch literal 148568 zcmc${3w%`7xi_3mqK-Cp4>r}*VvRbUW@v1aHf=K{w6kFk?C1oe+@c`T;-M6&qRt>% zgy75oyQ`yVQLDABp118eytO^r+M}qgPA-!RiY8GJM3IY^*$hZPg%Aq!{hw#;J(mz| z`+eX0d;Ljf@3q%n>silw?(11=uL=aGj8T*#=Rc+B+eNuMr?jZ({)uCPACyu5-?lkTOFsj*8knN0c~^?ZL(O`>CA4m%55 zjmSP%O~Qyzq>fYcXCvxnj7X;oZTgGUC#F@j94%I(>+xvjbi@3B-cX;MRk3jOuxq?} zPXfQEU+P!y={kLoib}JWXN=2TUXZ;!{o8cucMXQmXnFS-y*w#=26Z>5CUH$it6?5j zpO}7uAs8Sd{&fPWCc%(VEyLU~$1o3Elew54ENmTZJb3FPjN!SlsA0c2lnGtT^i*^B zX`037XpsCYmRObM(JtiYHYV&I(|ywoiFLy~W{A7*$E${KC|qilp%uc9VfHcI;Q{EX zRaSUCoHE4Y8>z@#$3?NjYHWzBJf5H*x-TJ`5Rdmb_ilOL=iHBz_gkI&N_oH2xv!P? zGzxCdFYh0wdx<_dc=7lsMH^18HA>NAC)YZu$b4&#g=$4M{+w~2No53A)CE+J04U)+ z`}>KLp7l7-22XzG;3oR^$(Y^T%a3nxD#Br%+c5znkgQ84q_6wvw{{$VcP znQlbh-bpXurlZ?`9Tj)`=kwEzxc-i;H`%?BE|N!YNF=Ug)p zC6irLf`%g`c#=mCB$6jqMF_%YT`1t;B!_O5BYBE?qko1O*-6!hS3bz{%5-(^*>z!L zE6SAQu=_H%xNL6co;&IiikQBnbN3z1)63ATe-Zw)tfT($yTShLq2Hr7v{5zc+;8Bn z9e3ruPEnI9`S-C#CA~#}03O5KYKUuwdOLCw3KHiSB+gPpJh=gIWaUE8<1*qiJnriZ zQF3u5UN=nLv&d#!D1ulq)$Z0kZWlf5j#S~E{;N4$ld0*gNz@D&=6YtKSg#sQ;)$5y zsTM&`ttp6;%=Puu0ugX49vVXTR02Ud3L!6JnNSVz6!iGI zb9$45XEOufI*}Zj*M{j`nZWCW=h#5#tXOZT)VH1*Q=?B2R0HPvxwz|&1o0RDbBBwr zGrlB8r^bFmWs%OMbELk3&q8XR z4EThBchq~@EuSM(fwl0b8Nt+C`cd_Kz%hgH$L*(oots~6R`TeLjH(86i#D^t{79S8 zXm-vt%*{0QAeul?=kD7kwn6$njK-2jSE8Wpwi{$Au2vQWXa*<4o)D*s&k|(5KK1U$ z@vDh%*acfwo+}=2!uujpj=%AerRElImu7xL6M-V}3_U3h6e$^H=(aMgJ3x(~Dix!R zcs>4>d6X^6iQ7JrQ24JB{TtWK3pZO_ryQ?Vl zZShPgp0R+?e0N~}KL^O?T%*m^uF>Xoh_$3y#FNx@ymqPC=N;70pjE?D>Ms)Oi9lil zYV>C-+{}pWJ)(Kr-FTXigrhYS+vX4~V&( z(8$1W$09-}p7A{R9ok~OmuUH4QpX&XUsphl`%(L{g8@n3(_ zm82p_09M0ZpJYT8#WYUq~-NtB}x?<58bDKm97nBl%kT zMSd+OkHqXIxEJ;DlCxls8xzR5=a9t8`B@6h4$7|1IagmHfAk{~Crk53dxFrIAP;U6P=wSWYFZCIKB^H0v!; zLuiHyl1EpSc#PO~HTnWUA7A2eTa$5>!)Yh9)ueGJOMO{ zX*(J`;<5@GBwb9d{}*BEf`Z*ZUUPBIvKvQFX04HX9k~9>m84&C8sb|I+HuX#z6B}T6M%CLvJ=TpZ!&<1>Y#TPT z5_{GruA$R&NkKVYDKl1g5_EH}0kcT`l>R+~o#!yNYBS&jM)vvhNKyCHfeszMHsG~h zhORW4-P+aG6HHcb}?%~jRhWVCZ?&V5B z^F2ADEWc7!cY0iw-}oNY(JbEM%3UR2Dso)2=YO@>6jP0gsv$UCvpVj;5 zX&#EAo~!Ikia)phYQ)oc(-+caE2hAunMuvpsos4*g!xE1 zT-qF{d0P$-afHQ+Ucgl_zsoh2hcyE=hq;d$@VW4VG-sBzx1958}6+mOln= zssY{~VO47002H(hH@Q1p1Ugid#rEs^A#d+O^VuYFO|PQG^kPAz{SJ zeue9zhWL}jBitT5B_n?34e3ng=@P1Evw$X^qt{}Yl{#qEZ4RlAw&_Iky0TOAC02Yn zJ{8g+h20}OGI?*K~}AtF~9P()_ZAtm4a>i}NJM`5Y9As764GeVlYCK1`Kgw7B% z5$uEWa8JUFEI~2m3K6vfbFN`4hT>U=yOdCS%eyBGn9ESF8>o`4g>4yXz_ulqPTD8b z0yIXJ|AHiwDN3ScZXSXc_l^{b+LiV=V1+!{f=2U%W1t7>f&yX{)LA^R(dZ6r#3-Ep zVF3mnvw@)N4ImHt{cQt>D#1^y=r)1U#dwEZ6Nw+T7S)*a-vb+h;+lI1j$8Rgb z;l_ALM`PR=YVzcOdq5Xtf5gBM;*-;>vGp@e` z22E)^&Rx10S&qhaQ>?%bUY0Jl2Aez+89G&6w&C$t;AFrfjO9zwI^2<4Y4;@uzod@}ng^ z$;~(SmnYxc-j;l4dp}<2U!YlKXESa3zm#?@aFB{&Mnox*h-8 z5Kk&O+laJR7{31S{kpk3vU^B7+b6FE9YU1I`Rvp*Og_oDVJ zjiIyc_8TXVXSpSLbm;(Y{au&2*Cn?RAP2W2fOVU{Q+t+%O_g?_()J?UW5mg$1kus$ z?Wp&1=k6c)UrAa7o(0g3rrUFE;`t_&w81JbxoZPL>uJ0m+4*+`&h)F(#5m})9l8lj zZqwS{FTa?eTD^;U)YM12@b5)!^&UoX%GGAM@}8gGqo2NYl3DWKdVH}G@V%o(eu{e3 zVx)acVWZUC>Rr_I=#A!{=Nk3xzC{m;aa#iB8xDB;$}i5HqfOh0V?I}s032P3#O(|c4 z=Ih#DshGHy?ArM4;M*%*lI7I3KS6Uqt7P6(mU%a?x&*HOq&}vF0B3eDaUI8K z$c&Dk2e^xZ@!zzR0&rSZdE(X?1q^N`)2bY&5$ULC@VycGmf^d8Fnmx-IdNGkvT2O= zwZ^8--HQ(Ouikwe?S)@4#N;88bI+6Ii}x~pcr)B3MKuYPy!fg%TMFm~^Y1gK*K7wA zb!Lc6lZgado|J}PU6aVI#_@1Ob%WU@;WGzeYENg=El{(+bN6?TSUexJ#;+KD!DO$c<=q-QiPBwq+0#(K1Q1OY8)Evg$I0>fiDW!nsL-evlx)FcGkG6tP{}t&{lJ~%q z;Y)|EjZAQb4~fYxUEETF7D|KU^in*>>5Fs>BS$~|5Dc-WFn2|Pn#AIwhDfqxu>uRO zN&*Z!sL^*I++jBz{vEFu6$U7DOiEpzZE{j4vi-%>1CMMm0@#kbj1H_SP#AY-$7h}S zWG}6`VE$|yL0n#MkpE#KNH(N-Q*Tw#dYU9y-+SQC?)u2d3W%YeAF9#CuEwwm6cIm1)VU_z_S2@0NVZl%$; zSB*XiRf6hEIFNfMZs1Io1FiI1Nxwn!HEP0@y5{{%hTm%tcedaG$Xtzv4z1X=3G~jV_d7 z*+6yd-UTHajJBP{hNvBr&+`RVH*~SqW}S}(UA8gJT^DR^(#`j^{-au^_CU=5nVxQm zS23meD(#}VYv#|Ra7_SYArQJDAIqWFc+&~EDyNW_a@Y}H#83Rbkx4dR?Tj>bHeR=Z z3Yv$5ge9&e2WoaW=B8~Kils&{elePoZ8;8-?c33OA@JFzT}flHo251CZ5Ri}V7{Lt zk8G#!+D@>Uv>gNaVuz zD!d)uv~Qe8jduX(hRD^9Zt04)EYk2wGqGs3HwuM(QCpjqbOZX9+f^Jr#2 zjSgfz$CWj*bRYK)=?Xc zSmKB^fipnaw6tKu2=Z2A7ABEaf{Z*XvK@;Q0Wql_#pMm+&kqBp!muTf(43V!Uf9mi zN!J#v;}$k}6B;ad$M&OaN`TKSBc5us8Z~qN%g02nE=A;uRizqe122{bL|_SXI5BL* z5z@A;9ABisNnwP8g9$+{mH%$lw(P#NsBk15--ClPoUo0=iRF1 zg(NvBr$%R?^O}Lyj~QQnWG;X;EpOIC%d*UJg1ADCs(>2EqZ3oHuz2Gb;$N7FScAFo zQa2a{*M@tsBDvSxrXv9Et{DiJL)?rOpZXCYbKbQ?4i#D?3CSWwt%)dCqxoLIJQOhZ zL1_ogAx4b)1UU0etPEy4qF7V<29Z`K(K0+Q{7#nwV694GUh@)F(>L!HSl$@2YyZ<_v|7nX6EvZlIpptR=Zp7nEU)M)L%s zA`4q1sqfXh)wM|g0)}f?pvQ`WN-DF{k;mZa>SrJM{qKKo{Gi`=*Pc29_As#&VM-V4 zXbsh9vo2g*6loh{wC%khUOQehdl<5-<^=`TRr+C@<>(XqME;FfM+_>b!Pa?QZSSA2 zbm?BifLPu4pXlGKI6PYBu^H65UfP2}a}cNk!U84?F)c9nKD%Lwbep-iS#lI;`{0m`eOc%D_OG;1G2gH{kzAb18twDc&+^{}LB)PJEW{6Qpvx?4x9Tj|gXr4;e(m9eCIf*UwgjTlkB?7XB{XGqnig zooql;`y0fqesp1&o4DCX2MjN6*ZS>0d~>Sbh%a@gok=yMriCCuz=~Vr&=pgYrX;Ll zOzNfaxnD2pDs~ji$**)3&*QhW_&fzK84EgER-96_P&UGeC2A~=1w%Y1wHuudk_4FlmZYa>jkR|#SCL%Mi%wsvQEWA>37KZ*y?>Qyq;(6Mmaur3i<`4%6LqTB(1z4@Cy8)T_~*R2hMB{&|q1NW@J9Cy`@0 zf?E`HADh0O{0H&i{q!b+>2pPd+r|3csL^QnXN7S!>*@JuQw~-{q(38D<8IK$A2HY{ z>JU6U`3_se=X$E8-z&=v^Yv%lPGhikQxp{?RAg;~@HY_=C2Yxc9z#4PJLF~=1~D0k zh;~RsEJwxry$`TRDSOIhl$kGJ{rLU`-Va<1YR}a%?5t~)`WoLngOi85V9{oogkE#-!SKTXpO0z}U;|WvKg60plk)v(^t;G5{doAS2EzqvfS?UI%j6 z1-6OLSTF;Rpm;I={qac|v)9OMGVV9Lo6=`eJDDD1!rX3G=nKfU@wJB!fTPP8bu|g= zdRQX1p9Yso78_zN2%1u9xK`d8(qjNJC@#j|LdxENf|^7CD+pCK)Pdq99#7y)OOU}s z{!kqogw0rhh9__?ZpgI>5ux~V|qc&4_9Ya${sjw%w)O@6rr;MA> zg&@||MMN%9G98(FpCWW}?czu1LD2V`hw-CEucsT6Z}OK#t^;c9(Zu$vQDPu;XQpkd zRfFD#bL!apns>iurgS?Z-2ftb7~N5b?aj`P?_LPUUqSToWyz*;W;^%%;KDOesYuB+ zgH>>(MD2R|Milc>H<29Gu?Js362ftT|Cv&twFy?7U3IC0O?eMf1&`r8k7!BWYo^r% zyS1j*1|px|o3WG>^=tryS$dv|s%-vaoM`KQe!{e+TnDBTD$Bndu zsD~J{q=j1dyKzfHB&cWxo1GUTofVk7r;CbQBPNJlG(1|YIL@^cC&(wMKqIhLpMq0T z@DeeEKSv2n`mi@_oEHK(V&Zv#Y^2MnDVQibwZU$O0mIUzF=0%&Q5pJvfb`a97~WOgDy zYI=2SAU>&BZD?;B8gpdpmnH|(za}{>*QHvam=0+hUDPI0l1Q$X=a~r{)FjPOjtWIr z*m`Os{C)%qQS}N#)sg>k;tCs5P!g4Uu0W&|zy2$*<|MJqOHE;*gA@b8JZG~DW{C3* z9}`n()cmCL0cK%-5@$Az3B#Sf)|GyN+s>Pfg*2XHTngnr*F7_M9l*j^+@Ap*I7q&Pbxg%eNgxNou|=-W?;C1D3Tt`bdz_UNEJ zM5~7ka}P1E_zVP0LGl+uz)mEMcu+S_NSsGHN}8{xpnH!I;r7E16Fq?R?0nv^ikYu; z#5ESB`90t%JHL@1RVty=DRHfZP%_8*9?R#MCX&W)7=-OP9lus*#}ya$D74-R>+50E zL*YZDZ}IzIq@_FeeD}h&q@b0~Jy%`$b2nXK8f)1eGR(iQ;H^2Fw3hUB?rFHNog$-d z(u-p4I)43*I+VeNfx!YVADR{GYip@x5Z#58vkiqr!aF-OHTFNawez@J#o8v+1<~SF za7X?cHgS;q>GKI_Cl$TGFs4Mc6UnwE-7*mujwNT#l7Z+)&h!|BUnr2>4EFV(jaJO4 zrv*QxP1fO;{=;RfydwRsd*9vIJ5s?szAqajf*3+EJw#4JyE@y^vcsuAR#RR%-+2tm)wv=)d5JXEsj$&fU zQsIG2h7|lnV1eAbGH7)-T&+?{NFo0z3e}M}wwQ-aSwA2zAnSROtn=-UXYL1RslR}F zN7VhQ%$k*k<7jw@mo-syM_!+!49E@&nmViF+B#6c^=I*B{xX90AH-$5YG?= zq-wc;C;g86BCbsS8e;tz2gc~;=t#ECKFCIy@5UJzqvW$L0d8WM@aL^9=tBCVdG=N` zfzqrm`0l8_U>_+T7wS1AfUGPYkuA*(5PJp8!CsjeD{p0f?5LTsXXRzahA*-S30f}8 zo#C%KDu)vB7PdmXeUYnaEq^Z#znlktOv4nn)@)Bd%g=54Cjajxa#A=`pSc767bVev z#^4eKJrzMv6g0+jEf|$9Gd&CVrx|Yf?`S%R;G}d&2F(;QA{xy720Yq2!%RB=TSvzB&ItQmKq7YUJy57GGwPn{Zzp)aHD#OyU z!lNRMpdUE3$d3Xht=sX-4-3SZpY*$VL^_$g4MSK0vJDLF$wOl2Bt;lE($IXkxN3)Yz9%fYImD z_q0q`cHDBjcbB}MWrnVLP&*|vE6OW4kViE%(UbX8As?|8hQ zJk;Ei9IoQU7@mM*fIvs&r7T@W@7pi%qn&v4kNMDMKVnD5dxkX0Nv!y%QK05(4`rYG`_Sh|+3fip*z3)Xtg;X2n zL-TeMPa>Dz9fJ8Y>_*N2C>5~?a0@QLERZ<5S%)920|rYvz4LxvKEUdI8&H>o zwLzxW5;6o9ks)wh5V!Nmu3DPM=+dkMub&Q&6hoU&;`$>Hy4l@-Ak$ql!1lA*uRglT z*LI7`+>&Yc4TldzhE913m5S8BCOb9#5apIp+}0reSVCM~XKsdsyiR>I?XKu)HUI(IotSD28Tl4{l~4+*#(ucBx~4zZzgviWsR% zRH(wbBvBghQHcl3ab4$|>(SMRI+P(GsvAhAeT;tfiS5`N?mJ-~)YQvgYBUFx9@|8w zp$AP%p$+WLMiNxSzI$cJ+efMUE|?q~`aFONY(P!#VGA)v`!0|Pt@|)JtHz?Gxf!5E z=}_h(1X%+ckM%XmDva3vaJkh1RDhrCa+Il2(kNLq4!bB{joVrrK(O*A>9HKui!>xg z<*RXRX4WWzU@5QZ#ouaeR{l02HFh^y84)Q>SyV3%OO0s}A936q`+=BYT8?3x{IyhH z4uAlS&1PB9Lj4f{K0?y>Oo- zSBXCx%oEv-1I(iT0(XjQ%TkLDgF(T;V4o)13Yh|RBe^j?S#dUpfL5;awW(9EoM(1` zXl9r_M?TQRvN|wIvvPvC2x&`za!G@DmH@^rn{k?$;zzRN^b8o#+Xuq^0B={P-o>hl z!%MdlFU|EV0x49ZgcYqxh{yS|Z4dT}G{^064Jr4)TEV@`rNd#J29gO!u=3>7IyvG|Hb@Ncp_bQb_q> zQTw&wF!^Z>dkgo5o<;)9Rp8(ITD^#Igk z9>STk?RBq_e0kQ%e97DxdI)fW6$3z1Wmo0jnP)UrM=- zizqfWpOjuR%?n0?3=`-pTJwgbgQ_474=vu0qd-9w?SrV-K^zsum)EI}9#Rf!KIC+5 zQ7=CPrzW8s)Qc~#m3yys^Cji5u5@d@jsWtT)yoq=!+co)-Ghe8k@KPScn5J=24LZ7 zpfOTQC?in?%7-3<>cS>5EKSSk#nRN1ZIUlvqRGteYEq*IaNl6QRp>uFC%F~@oIX6( z#M+!cxwgQ6SnK!?GH3;yH51N8_z!uCNSncGsG?8}g}+X&!hF_0&Ea!`cKjCX=C*zf zhLChwz$c`4P%ph5{yA{G6zEt4gwMwmz~Fc*bp+c|^2Qk}&(~9+)U53Zx&p*t2qN=5 zMMd<9T{L8DVJbnVN&*3Uvj=q533{v4%wD?h*O{Wtmq62}V)nF5uWlwDIC4}{>8p14Nqqt7q>hJ0`{{`}{4^3)Sjdwl zGX`Z+ZP8UNl_7=(1R7=u7<>s?&evgHa0P!6tJHE_*hs92%WE~UhE$Kz?`_k>t>jyy z=<+(HT{-A&!(AQj>XiX+zcL86_cOzj-b5Y<_MUm%L7*1F6oggCEF;lRq42I}kzj$n zL#R>j8&vO}hA!|JO;7cst{=NP?mmmk06Ll?o0eqteC8jhx?N7%+!2hXDRnEFgLNPK z3SP-~uu0F+GP?_DI_b~yxEe){f2#5LU*aEw_-8~sMwZ}*JF6=UKAJvPO&4QS2Z`*sm(%wI;VfQ!CS!>;s>lY}V50vA0DX2}T zPnw?DNH)pCV{9Wg+Crlz^_u4!(lS84Z^%Q)3)!?z=d)w%XeEOB2|J*PjVB4D1>)qG z)KwOV{I^n9yv@IJtkfI1@dDfD$$sV8E=O-r(aPj9fgnE)PB?e~$FcC~8XP9Y`3ia~ zHnFUnT$UPRH#@w?ZuX~W7VA$=;4~BZj5rOuZqG!+>CZX%6_b}{5)xs3cmU*0Uh2eP zAEO)`0J_0x@jGZSZ?L3qoc6_O0CReqpPS7hdy%n7YzM$UAB*D1^&_gCLE&kiF2^nZvT5u z`$xBp(mqo*TAHrYQWz1_9JGF7JN{ui+IJ^z!w#*9{nXcGMp1Ixfw%DhtZ>uB7igVq zK@f~8iEP`61V(&8;?q=#NTHM11BhQq4Xz|4t-Q=gz4DG6^$R=gQ7-^gyq-tP&T^@# zK&N3h4NjIb#Lss^%;5SAY}~`jMfArc0?esPQfK`MZsHIBhUVllr&zuOYYjKbn8O*05pv?FO(d|5y592eTLpFY6#^7K zm4KNeS4Ok+qhU|!Fz=pIr0d(Bzggr&fr9PC4} z5xEUZfeY+qLtfgfmaC++Xu2c0YsvEs=FYrD((>*S53iAueFICDH8FmhfF4>Jg?+)Q z$A-fi!xkmtl<0!&tj@OER$`;`LhQB*ovn*Yt3maVaRi{U3tL2a#qoy9&W_v8PAD73 zgg%SiqZN3ni%GSbg3wsRO^x7j`V;`2FMqh$mYp=j^Z}#LA=EoHv`B!)&JB2s! zvMo*DyUA@!5XHXjhP|D8uDGxl;(QforL&{K5xaD6Pxrqt%XZg1oz67-FwI<^(e$7H#*H%&kweIiSmQGDl841tF-lHjk|>WnLzpb0(25ko8%XZK z4tf}hkrDFEmkA*)R7>6?*6Q3x_91H|Pt0Krg@-Cs(UeOKkPeRF>kG|_^{&JkZ(UL7 zG$ahTi^BhInC}@Tp(J8mS(zW612I+(0p^E9Sw2{Vvr-}{gxgTR#FJ`6{q&1A z9I@V2n=|W6hRh zE^vB*bAE#1yMF^}gg%=Su%QVkd>Dn{-Ru)#IAxs9qQ<7u%aP8C+<8xi_?eW;X!<;Q zn%y@TcBgma{8M=rERpyt#)SK6rI7SN3kkjS!+4Ic5KbRL#wJ`old=Ug_X9L<(1|wvyrv!gJbTEw?{Wfag^t-QPD3HN7Uc$fIP8?3| zIZAR>;gzSDuNmf`A)b)9IUK&<`V%J2hSQ?ec^=EcRzAYP-XqMX zU(#gS;$!5T@+;&=#xN4Q4rj`2!6LCuwQM~ANH&Sv72njV@aewU)oOGP>LibDnOaYO zs#0Yeh&Px>mx(Y)9g*lxNIn4PtDgvh~t=I=h?jgT7_W^X zo}LN%PJ}dmPfROmFb_7E#~RJPpfU)HCym`S63$4f6ba{{hkQm!_z*O*OZUxp!M;Lc zXdwI?LC8SsSimX^N^eK=y}44y+Wf-SM#>344d}DmYc$_%lx7;9gb$`lAEAgyjOao~ zl&1^}*>)QN-$$$30$3J#C_#X`!6QZ#> zFaUWMtHMJhpz8R^;)6*QhG-dj!ET51=!aS9uNg}v<{zbeuJoJWPt|4^sv8G1+F2Vty^@~vkO@<(K3I@vn zs6;Gue74=6m|6#^aXNG+&pz1~t141wQ|1^)-9ux6hSahI?k8|lp;Jg1A%FA27cp#^ zPqupBPV|{4KIO?pwqU|k6L^?vTN?^iOIcawoP0+6Ugh=>dw(V41<+kadsIp&Ru8*n z#2%Hbyvy_iCtTO?Al zi@3oN)#DR?n``K#W1IdL^<_7;x^pM)D0FS%x2P3SObH@c%Fo-iI`#x8s?IAMA@oB;hQbg@oK3&XrN*2+D^rdW=M?e-XMI?PEDiJu+FKuO^ z^>dUthVx0gr+x^N^t1wVbwP4?Zd>x0Tk68$t9z11ztVqe0Dq+kJORe{PGWXxFCtVo zJXUW-{>j+M?$q_K5~;nFT7YzXHWr6rEav7bYfle1Pj;t&(OQ_^jku<*%bmRbMFq6i|Bd~0_}Ibil>P3R%BlEg*-0x&N~1AE#Gan-x^0d z@}u7`K`qc4jyu5?Ph3@MN)kb07gaqM4-wI>P+-SWgdgSgSiA;>OeCnkgs#0k$*r^B zPQE@qk!+tk&Fu^@N%=}dI>S|nr+~s~>84IEo?nN>B$sJ{Y)IaD`(wQH*(NE6~h?ls>FuPoMI#?%jc^I32IqA28nyD9;Cc zZ%~zI2-i47NK;-5cu(l@aW$wM@V&07jfbYj%c?bHAmHl{sEr3@g0kit($!$M@2DDl ziMCiig0ba$ER@WwM(;(bk3C;CdN;#xh=}{_eoQl{A0?^V;Vnwpiaa~g$Z^<#S$cvq zU!;3C>)s^H9gmr$L!Ee=(qXKKVmc|MBZBW2#Ae~5U`{;VB<^P@DK9n$;ELwRdK|TE zx(T9ln#}Qt_K0Vy2spt9EMunlxMg_u)m-|ZK|j9N)aXiFB>QIX_Z~&W08Z)VWd>?T zN>E&rzj^B!tmiM4|r@CeadKu+x-5!YZQ@AzEKrNcVDFq=H z&Pzrbl(!#cb#@s(I+374%(U_nV8Pi+YU4}t6l4T60={jSnr+xq(WXx8k0k`3gp3?5 zti_t`nmX-etjK~o)IhsE9kH8$3f=d(8y%>z>u}@avxn7KGe6+`ay51tZmcWt$FcVa z$B4$9%sOP^N!HPPht)_I6gf>^z`Hr%O_H&SRY#t_m_{9dEx=5@;WOkUDRPoVuoO67 zNiio*N?AwHVk-u!#%@Ccl<)}DZc^9$jqdDOKuNp0<`I-^#JGyA8*s(*4IV2;0Wov* zYiKBPR0%C$V%jC)9!DNq5~NoE4~WQGh3Z*)1oe_!tc9MchG?xyP52KQ4CPj!1mmx= z9?hrU!q$`|B!dfN`z5r=ERHwog`d&^s=TQ$k!%>mdTOccQfDz!3BibF7&YEb>z-rz z`XIS`-s>3jHg(OP(d|hmc>k!X-FiR{sv^ELV?6+Tu<~>48x|y17wj7h5&hL1ww{tV zQ9@T%?djtDpb#x63ChS3f_Ca%D{pkh z*h+?W!RZb?boxp33QX9?ynlw+$cy-y(EPkNUrApHe+L8~Js+LllqkkFUK!)%$|JF1$S0V9G*MRzWMJ zhOY+!9doq=ts4bs_Ozh6mI`=~w9=0Q2i52UxNt&E6E~Cad@J>J7zu1Gya3Cz1`Zq) zQ4Orx?EWI0_#eUWa%SouiB<+ zo{{=KWDXmt283TVZE&wciN68>{L|*D?C}GZVl8+P6E8<-zF*VJ*?(MvHpbcq3$W4I zlnqRAZC-(|z}rt-GT8xHEUK3F11N=@Kgd~p-$<_Q_8&1k~U=x^FMa z_L4{XB8Dq83Zu65p+DYXrA9YWsoYV;>lU&%1R~f_!7m5q+prwnfR##$)SsX~?<5Z{ z>FMma>cUr)&JOLuZd!*$SniIxHU)Z=mPpj-|KKm=BmPplFizq?oQZTFw$@?i0|F(y z>O*G7%cwK@_PPZy6-LCla`u1j`w-uvuJ~ID;u)P9v&|Oqcr|q|B4o9|Jd19_aQRCS z-p!i#Lnw=$WiwEDeF>hk)zY_2r{_qlAO9x(>4Z|*iF&)$wP$j}^EzW>hsA% zSNA4AXl73)`J<{`;H6VFZW*&CEtuXAtd$h3m7|&$Ic-APFkHG*mcF7Z7C>t}Dh(JM zuA=iqcENz@R;Rt@7%&=+kx>JCaq=!3F?|8ElZ}|&Rz0%>0A=khp;BuVzk)NL&*@rwQ*fHcLR*{=nnGJr|=CM827vU!M_p-4>@zUt4fE5N1 z()L#(<7u8>c?lj_mC~z;8*07JBNG`3ywl2*SCI*|#YYDwPwAteTy2K3C12IdL&PYW zcOc%B@p2KQCAbG(p?3=ysT3;G1x$q;_92?;tlE*;&E zgKbq#@FRi`uQau56GERd{kdj)su&ux!R&6nx)FOlIihX3(Kwrxd&k31aCR?mJQ;3o!!DCe=&_6r-~sKi3)ho+3>zynaW@f!CciZj zFS`^Am&&WiPisYKrX#hYo55iFfdW;?x03azmC;6*wJubHOY3`Hz4N<7*V1pqmQMn2 zoVmmMB7<1(fC!+l{Yt;ZlMVJ!U^7;&(?H47b*k!s`?lyJyF z-nnwu;`?`4szg^D9`bhB&d>7zeeM*u`MShf)mHE8m`b-Ytn^`C$I+x&Q@}G!f&~de zh+p8m{cQd&(<7526XhqW!M@)E_5Hf<4Ot^RC@;l z;@UdOk<9dH$}v!3yOIf*T^f8}^8+vCIG1SR+Ipqe`@HXvc~G6QiCmW2OfRbT;wcab z67@b$L<$iPZwB|JI3(5O+oIn2JL-Q4B@&LH%}mX9A{3D3xIEIFLc}PueN&5(gx+A{ zv_|s&UA!TS^7d#4rTGz(8LgjyOtSVzmR?H{4fxln75oKKIFcn-Wr)c2E=hj(k$xr; z1IgmxV&xTZj!m+?odlrVwnqNFodStOM<&@dc_ce8pJYpN)XH@6$)t*8VIaxn?I-x? zdksgDw^t=nbC2W$SuTMrV<44RElRAFe#{8Ey?O-QX7LyBZgI$$h?l(f7m0eOx^=~7 z`l>$7yCs0H19^ug$E&`E#91B0gu~unwa&{Dv11RP6n`TM_~*iItASTwTqk)tlLm&w zPH}ymxU39R8`Q;*YQ-&nDMB>`>Eb=U9$lT1fXLJ`Ju%Q_fMseEouSD>^|0nen(r2* zr1$UD<5y;|1q!0}Lpt0e;C&?k3-8E)hI8X}?*P3(^xvU*kI@?|Fh0<;i_DgC3L!cI z*i*uRxH`-`1>|@W2Y##V`wIJ)_fgs5Jv@eC3A?kk9rA=m_ayF6%4-7nb@NLl9{R!Z zQo0`Tbj|n5&69E1xVJyDO9|b?8!I7=$HJ(R`de%ya>PDFh`#ND!TfC}9y=8Xu75!&QTr6c6WT z*?8zq)u1byImW~HB_3Ld8G(m~NmF&UeQ$gh+AH(W)eG6yZm-&ze$tNbBonhU$@cMJ zeD1gm*HG)(sFDA%RptzaFqHLKYMj9mhu+f{HoJn`(t`3YE(w z5CZ2=WhH@k>#=#kgWpP&RDc3->9PI@Okq96_lkPw6S#!1f+=ti_<2{6OZ~Pk1di}p zW%AHGSXho=p&g5k2DDWwp%j{wb>SxHLTD5~S|tSxc&&oeB8ixz*aVVO+azLawT(Kh zw&o_fYkMv?oZnH5Wjf2hyCuq1-d|7X>};Dfo_5oe0z`ZOEzgj^S5%}O;eZHT?SM$? z8deBEEXm1031IWb0r;wQ4FsU1-|Rf1=XypCs2Mg4r0!_QIjLvbVO5(&4)#6CzTd$9 zlaE1;$9fBs>a3$7l!Xbn3?Cyrs;FyXm_dvTXWpYp86gD~lSx$txk{oH28_;m#Yh+h zZDYS_{|P+7Wwj1^sEe1Ksw=|)$_00-B3}AcR_V1ET?sUB393|C0->>7|KrF7DuqgLH~-P>*xd3(1lxG?)A1<)h_5COqGr#WTQKL249dl?DiQq99&#y%T6S)~3X zd-*?}&DkfPrJyq?5J_fr7(%TUuXPc$u$27)F%34$N|+unM4l%r16gf~c?^38I>>0Q z$EkE0max@F-_&pnw-+aI&w~YmG3YqS76i z$c_>+R6%;MqahV+m3opLO=c|_sjstm0Dt05 z_+{L}X8y$*O3unYTSCf`hvL+qU}aAR2if%DI00F^rOFw=$)*eKK+ib>Ky87Q{h!!} zQV6&dDUOw$(=UZ~iyEUd$w$~Oj9;BrW~RPO);-9fbJxIl^55O_+(@MB>1?|ayWWQ? zfo*A-BQD$rRBiH|xMLw^G3au6iSjGTqPa*V|-EoQ3)7h zEJUogo2Jn`?(OovXbxh@3^|y}pmMx_sQaVz*&~G%DG}B0p$M(|8x=2sh|AQdh$XgB2 z?ZPh{f@Sqku%*&Ma-+!Q+ja}D`h6%nZ~==Igf)l9h`|VC!(pwtx^4!NlA0_ch@yj0x0$fIDyDt=XUY&Qlci1+>t-pzZMWRvdDL z@h>J()T^CX-;R3uap{DqzJ+Qyv5$fv;(uuUf>(QF=mD^~@#Ppla$}WFsBX6Ulc|?C za$n3sUnJ?pfet01O}GKaP|(-j+0$f}2iZkP3o_Rm`5JEmHc{EGGid?hm`&qpLp;(R z*Yn~gRKnagUX_UTk~&5*a;><%o))tKm zc7zhI#Ml?WSnrgQUbYrGsQ8c3H;Du(sKb)l95y9-JC4t;F)LuUjUtA#!*C z;U@761;VkwnLyMb*h9xb{hllq{(LW)uz$egf>p!9)k0w4!6IsbRt*hYP%pp_RM%KFoPY5wqO;(cyU*zn8q5FSn)vyZ;uKONw128rA6mFbV z!$0x^d)4q^+*nkC^_W6?`*gfGn!ODYs9;S2@*|xy4*Tiwfld(UV(e40LTHQWIspER z(TBV3c;8la4MoR+Z^kF$efR(>tyIW(ADyAh@1Z49=2dXiE5Wy(R3t`pj}r7udtW`) zC8*m9lBKWVcBpIar)F7B=6w;D*3(wuLDt?!3%Vm^y zBo~lOu-=2MGE&@;A8>N~?;o)n4>^fg2BIC`_hYp6 z$_D{)W32-B@I%B#>hU!{WwX-Tzu#_H}cj#7=Cc z^LEk@CdErGQiyj6vE}gq&Jbv$&0z`}(j`tu(;#H*=68~ik8sL}HK=4~Zh8Rcju|DgCks#v? z&fxy?xDDYR5O~dYiuvQXjKes5KV8S;vi+}4cB@?EfFW{6v1EwA+p7lcu~H)54`frJ zS`3u^H_f;I=I65Bj+GX*V!jwKe@WrgKaa4w5G`(Sup>fF9gl+DlaF0QxDk z?l@sDfs%=UX;@YG&|=MYEY())er3=zGiDTmBW zST2@<_G%euhZAww`*MDe-Gyjl|mxMtAcO3n)M>);D|%sd$nWuynzvlcs*V z3-Zy~TD(2HG0TO%$|2E*3u_JpaNqHF>w+y0G3Ud zD5dscRg_R0v=Q>bhak#x?`yNLTb;i0Yv_ zef@{%tie2iEoz?h#WW5v6L$AKuS&ZcUl|Bh=j}+m83*5*UB!<#;VpGt8`=>wXPEqL z`Ru8m&yxC<0k8LzZpSj`)GV={%r1HUr)mz+s4$XE|C_NvveSl{He}vw^A(?S)J;{h z$Payo^`yl2-;o~wkMOce*a}2+m@*Y3Qj}b;T#NUWbQ#!$o6PM}%+ZQZS z9?Fp!z6OCwb4GKI9P9mPlgJbKt>;nuJZhPw7o~fq=taL_yf}3W_*<858q1~Sue5KV+y*JBaNrmv0uF z1!6u zhsGYHH{fSbN(Tv>gcC9S>qe&AhOYE&zN6Z9hf}^yi~t%q%w#$R5lG++W5jki{lWwuv*sjp!4;|5tXYYtKO? z%a1>fKbk7K6=IU9&dxvrDRYJ<bz3O5)~e%NtJ=p#fsT}r8$7k`U-D)})$6Q}bYscUJOP5h#T zI2`Q%+4T1v{gge|=N*|HByaix_1Lc-SyZ z`9T%R68;nS%}_al(B#bg>;@lf{=?oY!hwm;w8Zc6(7@S2Aga0-?>%99x}1`_us z>ky-x)e7#hhlRBVUFO7bPF{CMn$bM|r%ja+4=(7JBp6BQ{|te$?(vXuCjKIi-$Q8v zxgNI2b|##fFD!z3oFYMWwgaDZXgl`oElC*WZtSJOHe%U?jSc&&Gj6;6{O_C;)iN7UYeE~o6ktYOjSTUd7ECO{LL^UEq zIMJczFn-5`KP}dW&}Yrz*nnTXr)w1cA@FSe0UhDH@qaxm?XoE#)K3bqL@JcS*s2tZhzY*-}3zb(~i3b zcJe3Lae2n?;{QYD?^u8U*W+QJh0Wivv&9Y?A~ZRxAEY%rdp+~i7$Vp5V7hCwlgc063ZG3M zBe(6Qji*kL>YXdY|ik;^4^a?8?EP6)7H{zGy!xlFOT?yQ1un^t3=3Vxq|A~^55o>9~AQNiJN4dolAqP z3yLq=hKU+YW8Q4(#{+XdJ#{*iSkQMd^$oh9$+eB57=1#<*off~3ZN|_^YLp1QJS^q zi3ip#fs|ffj%U*Pq_W>4r^LFJS6N!{F8o81HZ*(hqA>qh3}nGDR5Ve0P&2!~0uLHv zZ>!M?fJ8?Siq+H-C?I^U^>?6N&VP32j~acC=3_!DsqFB3LGcJpOwPjL%t!k6S%dBJ zU-1h%HS<8K;a>T>D=ufv`Wk~BMQ1cp z(l}e*P(9bO5%rih^0*~705xEl=(e?+R|KhN>u)HOmCR!McXF{M2z`Z=`79Ir&tRij z*WqcZ4g+F6_!bn1SWkxC2J8{*K%CL++FSUd8N#csRAfIr z#g%mpTOXzrhX|nV!M!ANnj^;3O=Ov4YhdLVHFi242gUbYRuL|Ee)GbUoDY#bOxy)j z<>@Quqo^cK&NBp`c59f&oNp7YCBnic2a*`}Oyf*bnCkZvQphbk*ZKyqW%H^0LMiE$ zb5UrAL!7qQ`v|@65F=*GO@kS6b}k*9TA6nMsDVs}O8es*l$DR~g^V~1l)uJOj^0)v z&of2>+oo`yMMG>@$Drbnc{=07z_}gK6DWaw3&G&NgHUeQl*h{pG{p)RA7qqbiy}@j zimw)Kk;>mql{L~>9oh|G%K%=&Te5vqns?bKR_I%{egjK1uOv9KF>IWBcOJhAv!;yY z(@i6vkNAcwc%LT8`Hrg$ZDN-_>w8v5gxLy0U?t8{GK7%q*G5|i*@6|1vk{IhP;*Gg ziq$;DzO8Chqn06)KV^LrS2*7wLFbQPSEM|D#J82sA8Egzuqz_`V~#O=4=~=vQ`8Lh zUsIbVfB4BTAD}Xa_ESIkQQjQbMlQanK4KDbyY|L0cyiO9tOV5&q|_8_+~b)G%1;b2 z_DSd5PD&03U{ny1VE7{rz$mllfzH2JLFZq*4)Aj4Uq~XbzK%wi&PSXpdkRZyMzJA& z&w~bj>01G-10zZ5ro zUdD2H5%sjt1^&zb&Kf*@Y(VBI;Kj_`dWrP!xPC#Lfa~HrPeflA8>=faG;0nONV;%* zJ8-UipQ+fo94N@O??@Q=YCf0#zu5D5we?dpF6Em!1Th&dOIOtW;9#XDut3od_%rR zdWgQW?!2hei#ZuPsy|pkjpph&a+nW+;F*CurQ=3vN`Q;e4&ggDvS*c8-Yk}EobP)x ze6zVNyMKDYpu~T_jsMz{@K4(EQ{laM>D58opp*&OLC=Si^bS<%|UBry=e#s@!y zGVflePCxV?PAVZcu)mROK-m8j()6&tasC)CPB_JM_yiS~aB+`Qe2!i0;^IE1_;tvB zs_o|DtxoZ;?BWV8-su#Ri$S&hTuf-Cv+rUTp*Sd7cH#$lB|FT}#`&6XMNVKj`E%$t zenm$8%@#FsF|Hfpwd?TdP_fc5o1hSE+Vm0ErsVa7TG=SDV3LtV2`VT{)k^w zC+70G$oipgTK{CI51kn1PxvE>zUC#N(?E0AVZ8}In-RXskx;0{A)iz3LOJN}_&WJ} z?`o>Ys+~-nxvldpH_7?}`XfihX`qvxkF1U#mHr;4#tZ1LpaVK5!ln+UMn{lzx9}|n z3Cgo*<#Y5}J5huFqgt#KC8dpMi{_91qgoR`wk?```j2YK&qy=Xj%ce#R^nP69}9gV zuNG}I9UXe2S^AH9Y(OpB|I)hsB~;7{beie1cJMQt5oDCq49JhM`f-p?c!!kRW`Cx= zv;7B0j>e9JK8Uo9p;sQkD`4hkYJF~GzBL6>nnyzXPRx$zMIN&o4&rkXJlaE3JwnB^ zMG1Z`5PfXXvfKkD^D8+6ml`k%J}nn6v~O3T7aPTlZX_2FjoC#k#BJo+VUmK%=8nQr z8?J)aRwKdWh#dR~!0E|x@W74{ZOU7+7a)w-GN{8Z=$?l^nnzhjr(|YDzunv@z!W}_ z11{{|uJJcAJ5y(UK&104vTQj#7+T`+p7CQm0rUDPG=$%+cQ}r>jS!qrFRk?Z4YLZS zEv6x>>cYz)VVfagCH>@mmm~CyMZ1z5d*D1CHk8$GrQDSY>jjgb8jbI9m>YSXfM)|M zv22}v*0tm=QgeLXrn6LCSwMxP{^7UH#o~dnl=_e(aEvNUfK4KfA0y3TyO@uH$bM4( z!FZ>(97?yhHA}?GMPfBA-Xt&eu3xkZQvpaLzOA809>} z?ECCIz|$DTpP2CLbpSw~XD9+#T)CG35_)XDy>4c*gK3y0Fg5NaOTkzWC^t+F5wU-5 zn4E{>n1|+i>8kvS>W)UFuG}h0fo<}KLBci9wWP91&iu>yeq-&&&37*Dyb*DwJeq)= zk#Adt7vAv+jBn`B|_uHH)DraR^iY}S#r1mhtwFpKN0WYOcwJc zE5K41cA>NGjpK7d7X=Y?#qX=+ms0#yHi(0D4yN0j_Cwo`VEf z8VGnmjkeK+j9&-?hj6c(e-Q^SVDzlQYZG&e+W0mvor{wjbM8?ndd~ zV(NdeA;;k;TJOG>qgdIc@=4CC`MtAUj6u9+_woO*_wMmk6<6Q*&Iv*^dQMbSYPFtf ztRR93_XuhZBya)=i4Y`S5JD0l5|WslaIsdSNx zTC}a=r7c>kiFiRDs|Z%!?^?6gIg{aR^?82%eLn9W-5W&Fq=kGy9(+ zVY_Cda;NscQ~hk&V*1g%p9=4x(vdvF+p70w0~M|81=EJcz71_B3ATTa3&c)q(GP*yeq3Y)*Xv83g&7`+uo;^q!>ZG;^w3da=sNl~4_(XC({+jnt zX~;c|c2U7fdpgt{pWtVh{ZvX$#Gnu;E^WFDYm2d^irGKKY^;J8PmBav`=)fYLfvNZ zlGJ^SwuPlAad1?+^TxNyW*YR0jNP2rj~W&@7Jc&pTWs*l?gIS9<{4-Qzrxw$tWjZ{ zocvAB%XHB`vpQddEnjGGvF(C>gNvcAPSBvgdi*;{cSHkKo$qVC)3&d)qo1#_`kkT9 z%^;@sXXxeqXx{1jIRXmUFhX5_!gKFHY=27Lp9eMmNC=7?#SgohiyqFjFb&#%0I1`N zO6<2svp&fK8qtHIQR)8%X07NrrjOPml0Qr4yR(N#3e1`g%tuLsW_);J9s46X=I=?6 zl_u8HZyK&&kdNiqZ}m>8r%Z6160Bh`eeZuwD;OVvq~NhIzm082|MTsB;|*q6NT`$E zK5>4wwZC}RVSu98{WXi$r(tMAa#XM_7Q}IQ1qh|~^X0am^8TTw9kJ&Zvv{$N^dBc) zwH`u*I=4_|x@I??u^C=eCVyh}Xfv=Xi|V`aBhq_&5Y%3xrK)>I2DSY`{WLY*&wmER8L z(fGdnkJo|r9NND;@+JG1_iV)>GZEguyyOe^FW-!PI0|-S|MJJ8aqRx8gXV2Fsj}gJ zFOL@Nh^>ky{);WB>)qIVGyHq_;-tms>7r?dfBX5vuhwnCsi(4S@a4T!^2f7Y?E)&q zCm)#UEA3{>qIy)4i2Yfum6e{!ri@SOiVErqLs!vv4N>ey-mz~GoyyLEiFIrSs9fhG z^zrso5pGCVgnhq9#iar#UVVq)5BztWjlrkT`{+ap>EFcn_1%Ri$^9yLT^Ghd4wwVa zLdO)Ri%_0>gX<~(W@S`2Ta~HQcom_s7OcLDe|$(GQVG$1VbRdT?F3;o@Yp`u?^W76?F@uEmjH|wn6-0n z^(wG(G<%YTsIp^Y4oEg_V);2uaEXS5xu9@>(O*}->-~aC$8nXf$6hrK#IDCkE@c^4f&gq zi2XfHeJe_Q2fNBWR$TB&=&IL{P|5zSB^{p)YTKSP7AZ)wW3H$1&89NqfLnY4i`~es z8UqRXlQW@qAG_J=u(xTEnR0fx>;xn16I_&7Mqkv@M|FEODb(FA+Q-cDZCQzx(mw-{ z<|k^BkW`J4cN=r-VX*JxWWDAFV(aT)`=kf&PS|KYsz!J_8{uJOKqUpQqTN9h7*tWg z(%!bW)eK)tv{e?g?rwWY`i^XaqsuC6Gkhd*B>Lf*I7MXt_FWrr#>9cXiJd~qfAy6i zlNg}xqp4NRth~;etQ92|OyZn~mmIb=sqo@3Huw8Zc4Xr~D5P&3hH@es2hk&Kp&HpZ zfFAz?k1&Zy$JRjKYKFG zV)A0z<@DnuFDQ)8w8ShTC#>&lQZDhgA1!Uq5l4oTF~af99eWN9b<&sPq3gbdza4u9 zhPobse021CRcZYB(qXShJND)*-)N3)0=gjM$)aIz4}0oSP^2HlB|MHE(>Q~GO6H` zE53%P6R>Gy#*3)f-4jSAJ%9ax-5zg2{M2fewe*X#Qx^Xt?4e`tL7}ce|8te*e+;G4 zBDtRAs0*u+N=cL~{>;G8XAW}7+Q%y_`t8zKaWFbi{Ea&9w-1Jdxbr90xbw!6e4NZx zsIl8#`ut5CAMnH4R-jD1b{5T3f z+;=OXGuc@ydq{Pik|A z^xjrNU7*s$;M}&Oh${-UZx}Jw^!c+;d>}Xkq4bqx4p{Wwh^03aXV=r~GA}8F30=1h z!X*;CTw4#3AO#D?;K#s@<6P1s_p3B_nnCV z8jkP3<`O+n@r>pb5q-2li9sDZuV_1||G-+PD+{JW6^;)@=p?pY{HiK|@g6gDcon%D zbcXruv8E8Lk0K%-L8MVau6(G-G*X|XD{iTw;R3?@c=xNM&*LeQ86HH5n1R797>FQS z`b{HI^c(PtkxU4?pzkbLlIYQz#~h1%t9>fF7_sviS3bz5N0L!a(i&fW0~XH`)AyUS zSMNJHR(po5iAobkVm6sZ)GoVvLBZZo=hLhmGr@>?UT7M9yVU$*$6GwTxb8tx8I1@u z!O?z<(Kw!7T-T%UO#<`u;<_gk-Xt(jFRt6J@Y@3O^y0c53LlA%EAi&(#dSLso+L0& zFY^8{EJ+>UqC_SJ4R<0B9Uo_4@2GflRU(88Vs$C7#M}Y#@&WN<;?GCB$K05hi3WIT zG#(vXinSma&*KcZvhLCxOfXg+VkQ`8CQ5$~JypJ#mG~9uvM63?W*BG2*Y;2wgd^gf zpnE~HnPCj90AHCdDS?TCT#?Ju3rH%6K= zTKP0FX|85c-+mcb0#(BnbL{#7om6gEfT^^OJs4?y6_x|lVH3a*4^!cTNA7?m>uda} z{hPLKzT}e+in<<)eb})%(D!q4ugULiQP!vc_YSC~ zeJRl=X)tciG<`dfLaKh8$?A!}zy_{{9Ic8z-cELD0-t5840SGtZ|$qbpQQZB-cXwO zJtjIzmg5fyb(T^5312lnSvp-3A8UP--P{sPi+*FV9!edpwP|CFh&g zQ6)v+isqa6S?8<%%2QTXwo}x&%wgS3zk2U|fh~|*30UTdYQ1k#ryUmhmnD3^ps%f( zOcMS1lpTjU>0>^PaX-aK*|KHtq0S+W|Gt{IrfBK(Fy%L{!pnXsnM8F=QqJOl31I|Z!+lR9FE_KW8l}XJq1rR@XuPq zI{`i)#5a0MVhDSf+OhTUez1GaUa;-}b}AsXS0hy?-QqViv)ACwqfsHNK-`>jd*& z)_3pxWIW_>3oTdgqStZTpY`W+EAdG(*n;ukyV?<<1c%yn_TVA^6`E7Y+I6J%YZCX6 z7E25M9=kP~=pxHfU3F2<1oKa3CY=`Fv9569vGhvxmH2dfVQypSBr z(~SH}^FeO~oR8A@-}vqwz<2!IVFP zwfsr(6Ep_g1c)-q9Q%Z`)83H;eKg@1jVg zOQ^L<9!nlyvjAM^f|`gqUCA7AI#GPrL}+Q^9*S0)_$e`xFLm+7OfKY~!P5Ph~|#AbPEnh)oRzQq{!^kKCoSgm-^ z!~PBE(~5p&$DhQdV{l@4B=Kt+9Vt$%A*;&h$#^W|)8g*q@*;8UbNxZ2;CIEL@=b~9 z*Z^>PA!u_z6u}t;nY;x}ar}2h-MIrJ!*KZL(>R>uzj2%hHU`*J@Ik2b*~H|^Qe#1p z_-~1MBz_%7kMnl?$wKH3L*0D#b7}nJcvl{Nne6L3t7&l(F!_&@pB$LdJ{k%TGZ1z( z=gphs(8Tn6m~d`u*A0%IYuJ|md`Wx6J@{P&V5DS+WDpnOV;Z`jTTDjQ zmBm7^F-cDF5yu16y(#U!CkMC4xuE)tZH*Oywk_U87KC?fH2CH-quCb^lorpZu48Ln zR}b1sV$gO7eW;A@69+&v8tps|GKz(icGqo)#)~(U$d@hBT-vYo#SbDO^IjwZUL4@% zK9NdJt2l8TWo>?>3P+E{X35q|D2K~$B*V(US;~!13jb}NHb1!&hcaXHjLQp8+xEfx zbkOqVZ67ScagKYjOXcNJtX62*iBn)c--Lw?FR)GacSA6gg{E+5PJ4fE({!jP@oVn; zq7Kn}bAOAFf;3J-M+nXPxydb@54Fy4Nb6AUrEy*}1Mns;um=geIHRPS=c+`>6_JOK z4hEFN`1{Z|@rP4^QpwIu*8_?mYZqalr6Kr*YDP*CW9=SXA=0rY(>}}NY!qPX?SH^H z87_D#hI37E<7v+R2gnF!&teYfP8Fh?er&Yk5h`+WBV<^it_P7?+BAwcAOxB?`mpj^zsyNucj2 z@WDK0qUfpxeUBh7lz&(@Z3vd%gW=p8deEp)K5(NvggU>A?o!_>>NDwhgS8$s)VTl* z`=a=h>QRZ8)y|3el=Ja3Kv(?<=+^OvP^jzT_j)gTfU?3qux}kyE5;s84AKsS_Ndrfi#73=D2DuzT0o=TP*tGMq?aHI7pTzPiwVvxTt;Q>GlWnD28bJ{U< zPc{9~BB!5`nb$BAX{|e&?0b)U}mIo^66J=s?NFU9TTk**!Q^0}iUrQ$5%GMw1 ze3obu_q8)AKAZRn9?W)PqG?QZm)4Ix{GcusW-uCmjk_sa3iv?K zbgVh(VGr5Yi9o!(DxLP#NZM9wnw6gd#Lk-B-(zQ zY!N=ff;?&w-Z|IYJIhJVehbIH1AD9BrCnMJzy*rypwgqOkIoNE+6GEKxC3b)u7Jng`5xrgYZ#Lsa=x z@qO|4r0%-@E-EzMo&!chTHvYcXm=#552L?k+{aq4f>!OycXn`zVsuobC{6s9xL7Ws zGxrJ5&>67%W4ZD!bHGl4*?0|!fef{9L=>$VMX|b{hhq60RQ5 zL?rmS!kqlqP?2m`xO`|_xtSal-cd_)FQfGXE18`UBGfs6+)#ICE~QQ1Ll>e6JdH%c zJ&LgXxDWkc2j7pQJ5L*9WAD=ZSCaJuGln$1$|>3_W(-?iGV=-EWkc8f4S#vb%r(?Y zfXXKzS>hOu4%>m3-kjz4C+^NI1c+4%6XIAfc7JXWehtTFI~lZ(I*zmX5J8iMSLR-b z1r4WV(7}j9(XH)@f_41yP5V#C-!p7a$DVNLI@;AHzJ1f46Y@6?+uX4i2%Xzy+Eb$( zosPpC;CGPaqVBSc;_j&!zQa1!=TXlSb0^?zyhQn!jO|4Qe3omZ;00`&_`jehn4Y7o3JtTCOjVZ+^5~AW#Hkm_+y*iJ0XJ(Q5yOj&ZZxO z0R(fT)R}0mu_PN_A=G&yw3YuPm1JH~cU?xL`=SgifGde(TlhlkSj=y`{6=eDb}3^! zA^X;XKZVNvWM%8dAz*~PIA0Ex{~=QFEHeG9le1pR*|rk&@{PCY{S|t`MvS)am&QLW z#l%G(FQBH)l1peu%q~)LB2KIm-_5~a+J$^-_uxZ{hkZzgK5R}rL@(R)_+;Wrk`+6s zzlftMCPaq4jV-aCWFk4807o1QKzU;ARI-qZ;!p7Q{7*c$C;yd#&7oVjL<_KSf2ivR zFgNIpx~g5&$A#sQ!AEg2N*Lwbu?Op)#-o2BHk|)4wvI0~^+dhw@l@a#8M&1W5)XH< zopJ^{IjD&n6RZ^HktHlr`WTCp-X*<*`d_|2ycg?}wz=!WX$YJ?V#f>GddgqHUopFl z-}sWJoo-|yw1Z?x!Q*YAzCn26_l?qmJ^k8ecqeV2;XAoqpzqz*kb4GgsPpfL31(e-ApUEf)9L!L7w&TPq*dE9|f*s7*cqVaIeLu%W2g&%U^Qw%CCuO}lzYKLR7A1dD7M+i>)lRGA2gE}O)#FAhOve<3#8ae;>Pge*If<4$sDPg ztNCHu(O60RIx5l9IG=|hM#Zd?#rj*ybnjwK2z&8IiJ;J~wS7?xSm=1gu-=>Vw-4JM z-@EDU6EgNbw-=RvJ1T$Q=O`5R_q??W8xlnLASuGb1of@tCh*2~B-(cv3I*pa>G`uf z1c)K_P4TCQ^;6W$KDSrQLl>FS@IWT}R6e>bWBYS^(Bgi0;9}FhbM}Zl*op=zi*c96 zA7VLZD_hkEis|TGr)vJvy+5^7B`SZZE7kFRBs zb@3@VL}P({V}Y~%v%iSUjmGz2Xp^>xrzONgxs1<*0MrK?eDY8{V5Lwl)wulU6LT*t zmG4v%*T1-(XlWHhsB<3NH*auuE9i?8-83A9A?Z-(TK?TdeKTwe*;d)RuMna@_r-|^ zs8uLVJd%Uk|EBkak4>oe6{CZpSU#)6mj!vy;iKI2>+r#TOyv49S?IbK@RvJV&mcpkGS+AYSZG=a1b$ z_EMZ+ewi~1h25YyG3dt)TVGRuuI%@TbLpUg7s#d}i3iAjqKR2qT_3l7hlbWxLXgPt z8^~hfFVM2p4~Kn-cvl<~e+n>JkPTlR$=?qza~iE%4flR}8;a4qnbV@xFkT+0zX_|6 zbv!Gvj^~(2qKguRjUI~b1=NqFx4Ww0KUg&gr5u$aXbAZ)FfJn3iPskDFT(;R$+F(~ z`EWlQU$v_79?CW$T#>l<@*(PWYDqPH$9!OaCH;EpwBNHGxSsm4(0@Hvumk;-EzvlJ zJCbw5H$`#Gd}k|?FDbZ(+Zb9;P1B^W{MKGieHhMs=_>`9`omQFO0wgP*=k*(r#@QH zNA-lA%aI`IyO)~hjb5_2IK8q)P3s^U7Q{D>|k3se=q6mvbadO zkJs;oa}Nk{1J|Ed?vmFr_elxet*V}=k}1lrIVM6GWJy9M5&$0fgX04)KXXS*9!Oy z1m7;aYx0d2A=-UmZeFtgmUPoE+i$ZNB<5GyKcXN)*Y)5pd)F86K<_$BO5=MRBv-X{T}MS~UA~|7-%f z_YjD4#Zu9?p?z3LjB|xAtwNN(U8y=-XxCS4Xl#blt-6ZA1Wbj!8@l=%R5xq3MZ3*N zTK92imiYsV0lD-rfyX*Z;iq|*!93o{ao5p{*0C=4KNIcPmDTZ23?9%I!ckg?&5l=g z0;5VBrZU2M0HZH5zd6bI;7W{44Z;7R$q8YaH~l&9fC+Aw<%VN7qTtS!g4>_j)}3sS zCdzWUNCD4$Vo^F&p>wx(x*`x4S7Z(e@F4Px38MTb(57?H)p|Qi! zBu_eAcUzawLtu8;C~5cr?$frdfGd(Mo+B6G^ES?TUmH~(9ZSM157{NR)0%@@Clf(( zjd#Cwu`q4U-O4lj(Y(WpTOn&7zKJlcQL6pw*B+4!mT`CH?x5`Gq=H#}ObgCaU-tYH zCXn2^Vl=um93`2{P}dyOxh2k4#Z9G;o^J1wv5*(u_J8fq+g7JO-NOhD{5M{lq=CaI zCYvk_)|})5r=6ssmn-`0j6AqZxxs@+9@+HBZhQ+#f2pIKll-Kw5ZVxb<$TYVWBfT; z_;o$_%l`ayJWvM>9r*2~!*;`;XDxpeC-~t|!N`@L5&O0*vI_JYE+mIkLFWus;sYt1 z#}eWR}<$wr!%wAnkDpW zZ&f?_UbG_Y-w^slh^PLO$cLM^W6k2K>6^khqK;ky;DC`kQ;-i(9D{w<8@r)VBxSjq*af#QI8*j<(5t-@^~C z_b9%;tI^16e-)=tZ|b`Rp)9c(=Z8T1Q8;NY?Av@sxVo_^wxq5lyrRCbwrNFpS#@Le zV*IRc4Ocg`)K%B63b(X1Hr6*TM)fE9Mb)wDhHza=OH<1k;g-5f+Uil?$Zt6F1q%fhji>Qy5R-Taxw zmGftxH@mX9Y<}ge$a(Y2XO$Gstc+Bal+T>L_QC1zRYpF-66xFrX zFK!H%)HES2{8$=mYL*o8@pf?N$uu<(%8p`6yPcn)QSbfE@6!J;vPD|=-e22cO1f@k zUCr|5@F^#^o`O=ZZ>Xz1!@J<*+Ie14_~cq5AejLPzg z`RA4t&n3MWbmkn8&zfI86}skd(dU#ovt|)?@s-fs;9XVSVH2txLQSHC}7X zTUy`HK>lH2b<4=sC1gKdOVgry)W;?8OSSMq=p~%#T~Id9yPy#NFP!H^FPP_5R#tjv zo_VGhjYhqbPCCgOF=B*w#u;aLmz7=SomF<0ch;n{ylM5zn!Ty@Ep>~UR(f?SR(ND; z-uv;Nd+&GM>b-Z9FK(zy!ONQ(+LqOMBgUTW4afg~^@VXnj~Zh7DiJfZ zUKak-by9xasQgi*ypw8b#xE)u;2UlbV#O8_8ftC6NjG@$TC)>3Or+wwolQFjMKjkBRW#AuZ|#A0 z@ebr8Au5V6H(asBo``01uEU zAGe7|F-YCN@|d!FbfphI#s_ck!D9~oXcmCq(n~=a&6pY;e~&&TwJT+O%F6s#Xq;Gv zNJfbaxAH?#*G;IhfZPn zUZ#ybwLSAKs0LXcnAOrIDsQ5rl!h-!RIrj1PYu z&*oSQ%m4O$j>+=&l^Ly}uH!Mk-M%v5;m`)2={9;v%)xT)H9Luq?SA_^c9Yn=K{R^0 z2p>YdX*U(5hD(r&VEH|U`XYkdV{KR^GE`TKl|))NDWytAS-5SVzHgYx$r?DJ80&5D z*DOG#10Sd}P8XF^9`w%-D+jb=QIsJfjN?tk;L3Q zl`5r=qVDOLUC$SVN}fXaX|g{2`J(R0nZPzjGRuzxJ_ZXk*@Q5a7Fd#j*C@=%1@<== zUhE|bCsbT)$`TXF8;~OJD_e{bl~TyTXq7QWjMp)N31M}lfy&GhCCWip1h1z$ykpxi zHf7?y5zN+1yqi*LXC_(~$y(Rtr7BANF&=shL&%4|$&#{SSdfb|br{bKpJMFCP7vFf za@;ILGv$b3fiFMhfl@K-kNiURDY>ZAW)eUt@5B#SCaU3qiAB5b&V2%5n1x|Qr&v&b zFUev%e$e&hvZkU*$stkt?2ROPn5F2~Yv7vMUrG8!Bw23{C5nrlNldz|F<92^7m2Qe z*!>Ct18PG}&e8=-2$yM6u%sQvUwYV!l67|G-UV6oNR^m(z9>tkrjs#QtIU)CNC%In zQTx--ba}2Em4muEfwIa`&bx>l$Tv_=;Rgr9jSj#gAC-f7IGoQOe`|VTjE)s2l}El3 zb5`d-9ugEQYNuLcIFE;UGaHOLo!YUH&z22LPYghn=feasE=n>m2?h=^*FrlXuER*# zV46cK*xJ&G1g?M(yRyhXP>Sh=0a*zx3B(=-tPTjWMJ@@;5L#hq3bu^E^*?AK_Vw=JuPj&4`}wLvtWPAMKB515D930x0?t`?vS)!xOdM z(oCZf=QPPahGVUh-Je^LG@K85?m*L3x+>FHf@y(_MF)tehm{)cEZT{m2RlWyqJ-{#kWe-GcEMXwaT z*AZV5e&m;g2fidc(!j@?YVEYx!&Zi=A*SZw+7SguC(Uop3jPtrPCXU*d#6^K|JW z1Zn#8c57b<=SD#Fhpe3ZYdA5CB5yWwv9aX#{Ed^g;UKmJSNyWwtp?p;|t zT>0H_H@?nODGN8g8?Ny+e{T6GAGPl+2@oH+V9cy z{lYbUzi>_8FI>|fol2UYwBMxZ`-N-ze&L$FU$~|}#z|jsP2VqE)AtM4^!>s$9e$&- zWYEr_rtcT7>HCFi`hMY>zT19;MHWrpFI?023)l4h!Zm%j{V8_8 zZNJ)`^!>s$eZO!`-!EL#ciTVhps4=+!Zm%ra82JYT(bG^n~w&_4{KYRmP8%(m(fY& zFXfjuk$;2#*1*3t@NW(LzpMf56pCF&jf6YTzU5}Retz~MzTP|gnWyP`N5Xf@J@p=* z${CG2v=?H0g821#)22*0BRq84%sIot`J+aT8krv+l{ad1-l#m&qosag82@RU6+{>( z&FCRa$6Yhz_t${YHQ3y|j7w*E87p%#zJBPStaWh8)ZaQz!m{N~SY8^eNU%xb`-!ef zFdYx1bQ%O>zD2>Dxxp-t`hlH--%j_L!JO5BNN`9;=CoiqPnUE*udhB%*=%u(2VEh0v;nY^z8}JbOfda+cPo`2LGH$Fl#F5YZCs` z#&2{zO-h&?%(*sD797%@SsV~4aLJ%i~qfX zby7w-U&Thp8!`e91s}{P5B6kC4?dAGIk-KeD7XXnof)-31eSkM;2%u!Ak#$E=dKt?If^&n%JaGx{4#JMg|8XR(M=Hy@)U$q8@ zu01Fc%v(J$5}eR6Xj*W6AoHY*;9Y^q!3}|WzON4iuEE1h02kq21d_lkJj?(PI4}4h zLV5zrfYt&mC$JC?5daq*5}W|uk>F6ImDE3%ALZpZG2T1zY;=~i%kz+NSR685k{#px z;IR;76%ywgRN;ybJ;W=`85mgZMMIg(7Yxh^29~ePIV`ZeIp@&8@+Fa+%)s)h%uyMK zfNloN3*|@Ue!cKmjc3wfH|%T3TGHX_0g$!hpjpAZz(O_}2xN?g>K5A>?oW#DuY;2M z=@IrOdYl?;&irOZaAheBcSi8)jH$tO8D+udMQIfh$(|luSq{qSpezDqNw7H=X-uN> z!u2*)B8YK7dZ}`wSb>({O&P_(^%?VUp9~=LtPDI&2XYSXBtkidtj}12dxWBt;9)KZ z0_O+s0>y@miwSK9S`Ks;?ok3RJW%cus_Rt;;;_4^*_jI|<=J4d0C!I5JUo;FsKuS7 zt;a(dfZ0m%ZK1dVcM?B9AyYxIP$)7FBd(KyT!1?X=6R<gu)RH@XKDQ+?oaoI>?sI+^obX>(bWeKmN|icz|{q;6eH zHqlLWYc1K*YN}fu1E-<3XYR-d_GZiv?#?(5_XrSF52_osZ6X$1`T1*;^{FWPLRARWh4m6= zi^S=G4<#QsD_9W?R#gNSM1xDFun&Z55g*9@U*gS5#=9Ke|D0^-*{cM$N5bjAMb~zt zNuR?yhTF;O4ckjmu+TOa6vY&1Z3?%J#nfg{o48%#UW8|_gxaP+CAF7i zSMNyJ!IEd&H%|*z1QrFWDuWBkgG-{p=BdGz5!CpSV8z97*+uHIr%*ae@P7h$()E9m z`ePeqpUpOE*L~FAAEEwMqW)5I5=C1x6>UufZA}SkOW^9X3XM`)o%nx;r1cj0MfNkP zw77jp`L!Zyvff7;l}Mu;X+$}V9c<4f2+TY);|oFq8`DaH7J>47nhY-7nv}!wuccs1Icb?|CCGXnK#lcF|}(z;2~y10K@>;n#H6H$4Cl-4Yt zv@!?5%cN=P(9@u_25=_`Yf6%7Ir_Ep)svBVdH{;8fMRE$qc9bDnT)g}NV^0|4r`A7;7gs8sYr7&(j@0Zg&Fv}Z(39rUX`?{PLaRqKnp~sL}7a* ztUMWpQb8bv4JO0Gbq@XEc<4(=Se}H7AqLZTy0; z9TL`^inoU1QG4`}giRCw(t$oxVc=f%pMiGMkL7+S=`QzBV&ZvorOdhmun)UG!tLc1 zrW>2=kxb1FBhCVe`wTHKx`g}8D$9=GFFNbwGdqRmp%l&S2rbPy3uu9a|30nHZ4YD)N7W2NX^?}vCV?*dHUvpMXpdprT81oCOs?>nqThlqb+ z2!C+>I?3PHcQXISg@1$cKPNr^>EK@qzUzhm%Veu5`F-AvGBWQ>&yL?|NZ#GTuO{h# zxefEx$8)Z{HU0?@{|Yi3T(1wnpOn1m`NRG;O22*q?$mS6{97Qcz9|Ewj}5~ArKJ2{ zsPD{a{^D}^d54p+0NKZJ;JZNh|AP`?{}i|%m10JAGaMYC zb_w4q_2OFi;(q<}DD}@X2P2h!9r2>xsq&* zJXFAQE@ekk4QOh1NpMIxpk)kEFLg$CU=HyipFiXX{J|9>J;Sf9h9@;+GMQr`i@dT# zvonWg!1Fv7#ru8cYUpq<$SWo8LSnEgm@^Md+ws^ScsS{Ikyje$*&Yb|Fv+thJ9A4$ za0hjg0@ZS_m3y7s0~ZE+19OABAur-0JIR;vz)gk`nvUY^RmlMEA5Ve|yG4e3lKQzk zIAjLYP-Ce9Iwfc!LxDL^&6Mn_VAidOpLZnw;JQQnYd5`5Nn409oesR4@r$j~7*5L$ z)HzUbcHk-)Qw5BEx>SOx=<7^DU#En4)C3S(iBNjWrB_sXNv7`dT=^ZiSP1AnlwL@0 zf?V50zWct4zvu}Bt_?oHN-T$F@t%g4xn6WpcSHL((rLPlD4`!_d{Ml73N1&` zEW|wmPG&r;fs6xJx9DER`Ka?THyAAsR$LH_MuLTSX&3XFn%x$RPA9yO-UaWL`0plt zKidy_|EM$*Duaa=u(YZ87*DA{yf-A?|ndfKl5Zyw~3^lOH+<>0kS4`rr$1`0d z-qnJ=LO@`7FsCAzm5ayqg5RA?2Yr=_?##6VIu5#m+BsM@+4U1bH=T5Q0gbywljClI zr?xiosYu+)WC0wNEs^nNT^-9sN9fEFO z&J+w#mt`-p${oJma*;g7w^I1bO!^@*<3iJKou1tgoKQjI924;BwG1HK*^KPdkmLr5 zcRA^T{X2$FGPh*}hgJsjF5t3&{nK#Lbf(`a^bN^$n&Hmij^J=X!p?0*Hik2SZ2-$0 z>Tu&aQgm(G0gpXmG$ha+Tv8cqE)T9mzYLY;YIaX02!N~XXANlP9At7f#v^=U`?B5O z69aORt!)*V-=lZt)R=2gPKbtEG3MG_g5lSyfi&{EghpN$@W^XL=Iw)MQ zC`Tqn_Tt&{6;Sd@8YRwa3=TzKhC2CDtBbQM_z@*U^{7JP|3&Ii|1p;4%(F4*N-ig` zg#F3|W?;3!IGM?IA2^bo2Y%~?-&s_CWFk%M>1L^?LpvUrhtivojj0kig9?!SQR4g} zDMQK^WR8caln3(~xS$pz8yLoh6F_UU+T@9UM3T>V1GySJhaQVRxDuq}RKG4=9h@Fq zHy{9`CEJC`fF#*RDMlT<31j-}2UG;_8i29*0aZj?2@nIR11bUHt$)C5fSKb40mT^U zfD3>|ftCSfS?(8EdXxUZw-1PMm_VQoZ5oDQ@P7|lrS{A!fT*l#_KDGo_Riatb-~F=`&4ScPIO!$gJPo1=`zo_?b$06m4&(TJ3G%G6Z6b1A^`V z!OpT^P~bfNscx82awP ze`{kZV0eX*dpla6S4}bhSPZI6p13 z8QG=Kz}rY#OkcG`M~pO%&PaET93nB)5nmBL;7_LpHPP zpXa?v?~T58&h1u7aC>IvuLcEoWL5-sq8HnXQT5%KMZrC|w-2aB=oJXVU^v2iGiM^K z3>e0*GEugfi-2LoJhR5a(5q$a62azzZi!%Zz{oH-a$qMOFnpSsc}nJixq&N!#=rO? zcQU~HV1GKQOm5r`49QG>-O)cR6P(oP<>#QY+y(5~4UY@fqNc*AKpwBaNdI zeb~UB&M}XJAId_yQ4?OjEB+k2=x)ugUmH z@-z#*n6x*O$quBaaYCY}xgff3H#dBMN!LNi`E-H3`FJ4t?-Kb{9~T2BK7~}Lagm>= ztA+m_#AB=cX#L6LT~I6lk1Oz>y0C z0^xadU_WI(hk89^0JwIWn|BZHBu|dym*>=h(Z?Eu@0Niko!fjGILX=Ll<)5a-{|1a z14pe++7zLML*=)hdb**#_x1ad?4G+f%G$=U*f;j$uI4=O!!bo9@@c_@OHt6O1iX5 zF{P{HOgwLoFq+>bT*q5@ZXWn)!0G#Jt#9;;u2I6j&`Eck(A)VZ`a-F{3mkf?->e6D zpShEWanXAX;XQ)${5tSClI~97L+`+J%@g{a(pOk*U@sT;p5YyutVdd&i-ga5N1t?} z5vAKKZ7R>LgBRH~@zJYL>e1ywUwFI;;kj`=ZtB!KJ*dp{2jHOCs?RGo&AUJqVoikSB)2 zbJ+;#5q$kHL$`qAdmhzeqW8!le+}{91cDOG#@o+n1&Fu}di zhLY!b@i<=j3(oVqz>5T5H^$KOoGu>A1ka-e2p7-S;$8)u+Cjavp4BKHq31bV5G@mY z{dg0D=VS5MCisE^gY(=e9%&4O^}}DgVU3X_MW+H0zPr%S^SmP-yOd9n!Fi4lk33!q zy@`5EApX*UhQudlhJhwX$WJw0!OI1w_iCbFFZelv(_XoR^WX$9YDekXBKQJ&*}|px zvx4_H_)CI^%lgy5A$Yssb4{@Kp5Qwje2?ITrlI$`g+2rNBRRJV&U0!A%N9IbVF-Ed z43D&?i0Ioz@Mnb2$y^Rc*wvFmh6^ra$y>hgsi-v2LlQDk@SHgY(0VaV@a=;0d>Kg0 zdZoi9cItMn(61B4@LU;!s~I1doD>gDfmvoc^(XShu|B;@PBNg zd24~EyrY1){fE#mpbio)p5MZq?3eVpu8!fPTz3e*UT|$eeU6^gJ(v z$Ah`z=XhZQC;x_kQ-1R(?0kALiywP+S}_&sQLoF0#N0?$A%@CgHhqq*)C`oi1HZyqf)fj_GJ?=bW{7LCUz1#iF0;5^oh$LD}kd$&OJqV3oVg7+A59@n79R~S#d zQQ;?F?+QH%pRX|NhOW`8jsn~AK}gS7<|3Cc}EDIbFTqj5&Y|d?-rcL zn-Ml#@b&-45c2pk9>**FFAct4KcK z06g}K$3;w!{#%a0!=l$lq0do=C-}pnpPU{;&*QCl+$#8jO$O)jR6MQ_K0CJ=oX1V^ zc$wf8j~krFNAb8u@aEqcoW~&Xcr9@1ANGU{F4ddY_EEVk_>;l+nw$3{rXS#i<+s|& z9m0RX3nqZa74i6x;Ds+4oW}?8xJ~f(mkrKifO!0a;CX*GIFIAu@h^h+ylHSAQ^Vui zf^XPma30^n<43^BKa2WJApY(Z-0eqs=y!5{-#4T@CWXgr!3#e$IFAXLNA!NQRS^KU zqd-r7pf&~Z)7ODh|9PF*pQis!!PP#Nh&`BgV~}^h!)K)M?{V-kf@?di!Dk5m7X{>A zDEM0rK2>n_ry5);c$Ubg_$Mew~2zFzQv*n`USGr^L{>v`{^nR-Jb$IwMRasv+CSFd zHw2e%pu*nU%pd-Q>t$-+i+>3H)Fh>O*e7_2gJ*CpWw|7{+{3~9sD1_)Aj%NGJeDX<9G(h;dOn&if;p1fkzx*iH8Dr z+b&Mg2S3IKKfwq8mJdGC2cPJJ|LL&wa!&W5Ki3Dp$Omus!LRheulK=k@xkx*!5{X) zpYXx|;Df*BgMa9Q(}~jQ%6+g8p6i1b_~6rg@CqONJRiK;2VdfYH~Qe0`rxa5@SA<` z`+e|jKKM&M_}f1CJ|FyGbOFKHmqY_3!EOwcH0^ z?Sp^M2mhfDeyI1L^eB=Y#L_!3SY#BpsileDGW! zyub&a=7Z1m!5e(=@A%-|KKM;O_)mTCU;5y`^}(O=!C&&h-}1rV^T9s`euVXY&FdV{ z0ovz7e~?c<vQr+0r41UD3)vIk@Wnm+0 znm|~Cqp)zw6i9G5QBzwC#~iUZbbQkiNZaaFH#aw|O8snI;o)Q(@GtNd*To9)6!+ttxLVdE!7Jb zw#8zcZE%KA$a>4drk2{e7B5!4xYcWDX|As2$C@Q|%j#IZQTaHq2NF@*qw-8i)htC` z8f)v8*EPnVGaU9s@{Y_?MafxFD_IzdH=1LQ@~T@}sv8%xZjn(6=7{yJE!BwK+FZS& zktxTpw8%y)PO55#i7dvUQT2;fi9T^w7gC1On^r8TudS1_cotVTw|aGaWEej-Lh2YD zWkpJ51ouTa%%|1EuLkI6aZ7!z*Vxjuf*(lGv0iQ6qUyE=Lto!m(+J(+#4RXg;W8Y2 z<^gJ{U&7qzv1xhgF@@Hr(E3z(@`)eJ`9WL=O^u7{7q_+4$q8$8rce#Z$*P#Zf5#JO z%+ae^1uK?km=%Z^+_OC~eUTU5WWsj<4I zrXE!j=flz2M$Ppt)eWd9%c**z&=)n;w6(&JjaBz6`GtnU+?F)8)L-h=pp1~GTG62X zT!h2DVkl98A^7Og&^p-D;~0-4bAeFdN!e;7QiHMB=9ToksI8%)6%`go6iFpDwnx>0 z)nG(b&6=FUvgzD1PH(IxU>JF1k994vRbp>){1IndC{a`7X?cC!3XcqsDmN^6G)})8 zIf{_ly2iQnjk8HbYl-91FKP=6?{wak$?>wLHk7uUyJvV)B9}J7G&m(wUgiiu_+3;7s%omJ71bm2y*3y> zoeV>R#Thf6|8jL0Q$WvSnb+8Sejdet+0Tp}!_Q;+FUK9ramRApu^e|C z$Hlo<;4_Znj^nsEDT@$}JC5Uyv zy{(!4@)>3G+nVKph|)#J8FmNq%uff7N(YWk2eMOMHQHNI^{Q~%A(@^2oQiZR>Q{omtE(~R8dgoKi_I;Y+0=q_4x`*; z&!5i*Kfh+l()o12p~oc5utKW5S4Et>sxlbwEN-_og(=)4&|gJ$i|QNerkM7+s;s(s zR&{+VvRyU1E;gm1y0w*3Wd4N^>r=K1GUpk zgfONdVv{SSBFRvg)EAk|eG%}mo*~*)c!k9+R2L8v#{|wo?$BqT<|x+E0E3dFD=D9l zlh7FI1^q;CMnv|irl=FuQk%W1u?8?z#WHkFmOTG}OiFlDa43F-GoHMaWaJ6-dUCx|oaCk>n4{ zhKxBULm)xQ3&1+@k18WIiLhO?0w^VOG%9ps&PHu5<)c!)s&brFStO^TvPH8Iv2m*- zFm=+aDxm^uj8J!z7y67F#qyeUb4> zNySiU+D^+e=26LhawhzjsV*u2Ov^YBe&G3vBls`Pm8Z^7ASiC(w5meagWm4ox(;5Z z)0vM={|%WZCH{mf{VEHmr3#aGdt9A z<^Ma2o_vVnG|x;I(Pvon9}7<9(t!U;AHnV7t^9v=0f-(sa}=l3}u`j;$vT4Sd6^RYv( zdLAU}6}24I4rln_vm9LWb-v(kxvaBryB_WH;WJPs0f-NM^PuvdB)H0{>5jGN53%Ua zxA1HWUufa;5$^|3R{(pLpARf`Y5wG~J^tJkOHzI3GUiEP7l1n|$c+^`ZZj5B(n;`U^!rFFUx( z|E9%T=@(*5*flp`LgB77F_eC^ha2@ZMVl*d~CZK;X^;h!YOUd??eaJ zbZ1%o?fjnS&})7dIJoj@u=v>dZS|r5wncB}tJ|Sh`LB0yP4{k#k1hXw4!z3%u!Ad~ z$1Og#{LlK(|H;Db`unoQ$IjQgKJ*`1xLvRJIk@WK2zu$lMYMK)!-A__DgAH<*ZhvL z_|UhiT7Nq&{0IyGfrTGw;TcD1Ra;&YV6 z=j%rsdE9iTIQTo_-=cz(KJ9+#8y0T2J0~5Jp8rt6iOk{)mk_`12fdN^2c;zQpeYr4Z6`dg(RdyRvu{?|MB zO+x>3i~rXw{x3W9%I7_co(_Xoc|LXMRi2}cGx;LLs}6pll*`{7T;>13 z;&1DJk3+9~_B*)pnQ)RxpYmnb-&ukOfK!;#-)zy_cKZ__`bR8!yBv4;(0^p%5u~g2 zcWy3z;Bw`>LU5H+?XAnf)gHd@;F_-=3qAm8oM@Hf^A>LB_Z1&LA6fKve)l=_S}uW; zIa>$#heHG(fMC0PkFfB6B24wO)WU804j=wMu;}e_zt^ExIgk97k(1;($jcJ&ifI%72aE zqzC#ISncX2ANutcy*+Nc*@ymFi++H`f4@Vo@*jCx|NN?dKGDHd{yf1+ew+UshhF(# z6!-xK-4zBv#=-?{<76;Eg$mHi~2Uq!D6`b;Wx+Tw>4!x%Pu7fL| zV`xwnm+D9JJ5+GupJ(wu-G_dhgAbN^G1T)4)sp zUc};0=O8K`wdg5r0hknN)h=i-&!lU@D{F^O4c7JJwMQ^8jrA2SI%MUyB zIxfA*!BwA6TYT(x>Q#qc{mE_zS3Y|!K4UGt9ZiGvxJY(;p0QnU^$#1R+;4Gk<$s^W z#~wHSqeHKJUa{!yeoiQ##W|oKd$NU(v*ed!N0WX`_4T;-W%;WQ4c`<5*foYFnR(p$SlZ|kSaqPO#PyF;(?{HKGfJew>& z6RmVVwQ#%M9W>hHmt>(mKD8X*5?uA5{6Dqm?f%=KF@}#zzesT6Z@(8T^P!Jf^tPY8 z+`?`7y|L-jJxFj$*RI!DZgAUM(6{6|^znFv$;oMqt@N7wmGvv8Y!sfFA01IG84 zXRWl4*$%Gy$7dvb5f9s+%(QUZZ?yT~H(0ox-{%FVaNMbT`PBO0TYd1{vh;j9eegGY@S>UN`Rwq)k1kJ7f0Bc1|1;0QwI4p- z!L=Nx2~Oo`x3e=Hde#5!4zB6m=iu5-z2bu(Sz+?!+HIlWT3*WMG6z@r*I9h*cKk&j z`v11*?fmZbp+DxF^!op{;3U7@-?+-5S2=giO6Avnk9bRP&9Bm5FgrzW^RE}&rEj(9 z?RwPd&}%t9V&N@FO8vuU7QWcRgOx@eN_UBc=UTW;f0~8c^k-POO<&}LS6VpfTIGLM zaKh~OrjzFYz@_?8`T`4o8Q~j)Oy>Q_!PkZi{yV{4``l&GQ&_I_+xIxQ+U-xzHT+Z_ zE#F54Cmv^6e)u_uUis{BaLw087Ty3}$#V3;+voO|NBLYMxSQX*9D0@i5sUt8Oa7-F zdX@hb2j4i*$nlzk>vsX6s`PRm?cl2a6CGUhb&i9p{1*sL`7N~MU*yoM{NJ_c_alz# zc`7xoxQLJ4-pvwR%U$_=-v@6$pV=hsR_WJX&>z=){mj9Y{?|VE(}I(n_BhNReCR*0 z=#rXz-+Tw}6nmTC;5tuq zrr;#MJs)(Hh1+`gp2J7ey~(1FSax-Xg-^EdU-2|4%;ns}6saC$HYfPyFrjog%pAOX+7>^iwUn zUFguCCi%M9!E>cuzQnNf#>5z-9P>i!i%iI#_T`SLs_VdRw2D`p{o#(cASpVc~Xudm33BmfyDXWlibv z9X@!l+0awIZ2paxq~|k)62nFLwbQ-P2mgcMF8`+G%;o?-2d_wvul2!ywbIbL{M%Qh z=aY45di)PQc+0m_^#6@VwUeJ%_;)OPj}LyrWrmL{XC6hyMf$t~|CRsQf)l+x4zSOn zxAlMPtG7=QGL&U+>@_iNC$m!PQ@F6rA#8``gk)|8#T3pU-x1<$r;LEB{8p zUH(t{(ErWBRX^El`^%&F6bD!PAAfC%K8#1T^U2qx$1k*Sl2ylNZgy}j$KN}+(!b!~ zD(BdBsdS0I>TR-vYrDDD!4DPv-yt~hu-9Gu&Y@R1pLcLAmz@r-@_%OWpJui1*L=6X z{L1G#!AYK|MSq(Q{hb!Qy^i8ui=L{Kme)oLr!+L(=Pf?=_p>iK^qQ}?9bEZ*WbrAn z$;Ic|0BH~as?+D?e!JI9eS1LYzKcs>S>jOD}B9#D}9%PEB*H!TXNocW0;i(2ug{?eEJLIrJ*ej~!h7)mDp--5=X-(MKVZ){7S{`j0LA z4U3-gp!p5lfFHQDT~q&)*hmCrp6u6nrN!L{7~?BH5n18z3*Q2E;Pm?sOa_M`msEPDGr^el&7<(%%|YFBd| ze3Iy4ql2rQj|on4PPhE_pB#EE$ECOQ*R$g5eDIA9uI2ukg-5`0t6}T)Ir!s(&-g+A zbXEQe!Abso_^y^3vBzibbm&i$`gN~^EB^-^ zT={Rb_?KF8ZgJ>U|IazNmg6Tr_>>(Jg0dy2lw$J+yi!{=b(LxYzshm$|gUmY!a_~e8yh&Gv15eT&CG@+I{wV67LrA}o_YqqSBW`7^ z_x3uMIP0g8KOZmmk=}eT{x3=J@5zUc_kHfOsM_awa6Q~tIP!Cpb1RdthX;xt?RBzn z_?$&Pe0_Dc=zID&Ge$W4CkTiC#pKWT9p~O(s&3o7)MuK95O$2&*=#Q1!TaQJU$FFk}s^*1DVmxs#r$XibM0?)(H1RpLO?{|$6KHGi9 z3y1$D!u$HTJ=wYC=Qui!3Zh3IPH!r&7uxGw=jOxD-zO*ZZ;+nvN8U~7SCF3PvAh4R zJRZb(a)Mtf9QmB?T>HrrqKE%_;pjirv&!SaaeahvXm%ku`lhj92DA{_clg(Ln3=ay$a zpI$F|_)im#cK@SrlskubeJBIx>n9TYklE$+g?_kj^q=v0hB7g2b^F@z*J|i6YX(hfqq|iRL6p33dFur~5+!+76CF?|g zzmK0?9x=CnALkDfj(Q#GT>Di%p}#Ppe^vCz!}r3`A3Dt`j}!51?_B#sSJ9)r{zEu? z_9Gwe4+n`J{ozpI@b51i{=XuB?hhx49(g!3!LJpL#dfg}-{&yt&{~~($ zKPnvl3x&h~*@XW~3H?&yhle`jxPFhg%G-aeG_gXy3OJ{Oc#8 zKYXCy^zZHEa(~#)IrJ#^0O9aCTli4#5C0_``D}1*_2ujN--#an-J4^ahzI;i;RF46 z`Mq$IJJY$9%lFH3L=XRU!jXr476yZ`ARh1`&ds0md9mo>zwF79O`8vR$EP;TtA*El zeSaam%Jbh}IP!3sbIrpN(W74L68z^+Z#d2ag`?a| z=V9USc`V`cr0C)Em2mj1OZfcknM8hs!{-p^9W_6qM?B+&!{^e3&sCy_&%?su^H{>? zNzudSZPIi9Uy;y1^=x^5(BD2y@bjK4*Q4A|girP3;tS!Z*UpQgkL8)?|N9c>`ONd3 z<9J88J3e0?56az5ILbZ7xt3c;oXf2jAC!A#LjS(#5zk8Dh-d2;Hk^ljiE}(hCHO$+ znxF9r{(^AC`KoZl`Mq<^Tjk>R_&Lr)6Z}Nt+&`Zo{!_5T^v3!e>`F!V^hb5%vdDpi^ zkL#9y2uD7Pb0@ptx9R81!Pe(c~7KrdJt?0zk>187j2j=2 zp8bCyeaXxFNzbL_O%3sd$4y4 zU*Yw7QaIZ2E#X~bc$p7{qrRUyw>bGdgs(+E&3!U&Y`DHX-z?|w|4--U-;dh2AMqoI zpOEl5mGnHGj7;b+AU&TKu1M&wCw*6n=K;~>Y?xM$WF;F=C2MI?! zX9!20FK}+T~|39OH-->xKA3h#WbB^&A@y`*C{_wbP#JQCGInJyNYGHvt zj`u#o;d7{Si<94Pzl1o)f3^4^{)^rz6c`NyIfB2K= z5zmXlQSMUVDEA%VDEABJ+8+iikM%{pkmtWRH$CU!e$iuGeO5TiT}(dQuLizbUM_rI z7CzOFqt}I_zV8V~xoe$U{5W%aG@TPMd7l?Dr8yvq4d;fUuV=Tr07v@j`ZB$t`j}#d+*2P<$@3V zq@2V5WakzS_p2eIN52{-9R7QMTJ8@%h&Z?V4CmU8Pm|t$2cQ0{%l&blI#xL9HNm-g z@b&zS#QD0n!)N9G)4V@a2uC|^BOK-Kp; zy@<2_A7Si+m@0X%SJl_dNJlQYW^T5}c$2v!S zk^eJ=qo1EkoZInt#JL?Cof|ua`pMm-XP*~H&-r{LES6ka) z6c)?RIpKqGXzgFFl+&iZl0N0HBD;;jFcILEom*J0>;*TXsIEo%8kK14AN5oPL|0+2zc3J}JS@;Uq zcM-nIc~{}9omUDkI5M^BUp(oF7K~ z;qV>(d4O~4pQlkjJeBxh;&sGNCtmN|+Sa^qT;D+4epes%vE`o(`=bEohb zn?$gXe0V-^k?0Z6E2QUnHlNOH>u*y%PM=Qrw>UpY`1@@{NzeX%x^DBw|GV*R!e>)2 zA9-l@`r_}0z^gWn2KKkxwt(aLgMS@)?%UpCkN!uh&Jytz4UXwdD%pRtEG_gyZi%{+qbPI`uSj$z-Mx z=l*#I@i{?J|0?}{G% ze z|BH#6e@Bo1@`V4@qKE$t#O+l+92YkeH~&uVe_O);PSL~vUgFK<|2N|1-`V}=B>W#2 zJ^Y^~zL5N1B5wX&-T$?O|68Jm{|CgMB>#_zoBs-L-_M;Jwk!we_xOP zmW2NuqKE(8#O;+a_&-40{QJBAtc3r3)q8tAN&E%!f1bGc-|zaD6aKG@9`V0Nd@=d| zleqcMcK=Tj{$Ge5{@)XSk^DQDX;^T4EpY!$oZE_zuPsFn{~d_G6!t;>cO_o(^8D}N zyu`ve7y7+K5B~#*zfAtWByL|vy8mI$ZN>2)C3^TDPu#Ah5zi^a?Q6aJ4{>fQ_8%sC z_>U&uLjD&Jx37cT|03tMV*krTkL%TIg%5O}8_4H3l;@j851%`QPxAh7cf#iZ(ZgrH z@X7A;M8fA8(ZlCe;Zxn`jfBs;qKD7N!l${<=Lw&mM1Q;MJ7OK$h2OW_!a0s3l)J0& zp}xHb`J74Za$rJ#uyFYQI^i=Sp&w1WU#P>#@Ui6r;#T#6zI~CejoCdKj*AA;Tb=R$ zd|xfR)0W|vVL`hgKUJ=~iS$+mj+c9dzvKORmhk1y=Q=l!%_z=QqKE%F(r-@sO7}CL zEr|CZ-ii2u&QY(oHxE08<(H)Ad8eaDZ}-T^=c&YBBYpkD;NH|6E~l((I(S_xal!Jf4y+bW85Mf{p}Iqv%UVW2*+`;+PRgv zG3B{KMGOr2f&Z4yO}`20cS-0gNpEv9Xvba&{eh%k7s`M>CwjzxnsCIKC!hVO+{;AY z)!TQn@b%883Wxs;;qbY~x#h>^ju8JW()XZx%_naAtnhLd3Wxt9;fUug=UVPc(W73U z39s^UzZMSvip@fBVNw5WoTHyCcb_f^UMU>q?kODQ9_(DpJz4a)9vdPY{-cG%|FVSt zjiSf(*dK($|4!lXpPlf3ETLaQ+~)D@W6Lt~8BYD`ebQTwa9y`jIO6R$n zkno=<`bpmZuMiIZYlXxAUh?0E;-4>i_%sWL&oku1^Z753-r91KKPP)tc;7p$w`DT# z61O%(xhsUD+#j5qb|l5W_ZH^Xex8N?0OzJZhV&;U^rw@a{|;yp>8)N1e0wf&D+A^J zoqV|5R}%VnNYCZ|NO~@}n?HE7GWmL}r*j-fi044k^Ye~_Nzc!Qk1Yk_7Sqs$C7ijHxM^|Sa*uFapUfv-^6>{j%ZPKF?+dT;b_s!W(VS&E&nYf*gt2SQg z=go=4agAoEK-}7^d1VAm!W(}VL5uJPd*~OIVqCSA+w^G!Sqm^Mh_lAuqq1{7^V)@R zJ14v_Bl5iPY;)uV;hDQ4ZxWt;F!GiJFA8s}i~6i3B`o%9`wCtyymhFl!n@0=%YU!k8!ywqNWjh~kBvNQ17}!}hum{nI>?tMt4Cd>U z7sRKn-wMb1t3|oJWD%BPf@gi+1Lfu)i2CXT&k1jw67~56FC=)AaE#mYh}*bY8SOJI z#4VpVKNf{&U7z*)an!3}X8c99@Y;Vxo>RUs^1N_dKNN%`|4qVi{m>#D?N}5J|LhjA ze8dm`YT@wD35S1PIQ$F3;ol@2{w>1cUlb1itlzi(Tl~V|pA!!Mym0vA{$2f>L=XQK z;qWgChktgF9>go zUpV|Ru3J3a!{;G8h{Li-^;bvULfrHZyM7sQL&amF9``ZupX>TnqHnB=`XX`jf6Vo3 zi5n`oKI7v${QvIy3gU*UCq@4(ar1x5^<9XU{KrInC2`X~=lUMR4OQl&zM8n{7rVX> zaYMEJqrQf?>0fdE0OE#(1dvSZakA z9*I0Jyf`cJiNYKI7Wow6#d9KW6y7*A@|!J=Ey8R3-w|jPUi*5~7ljuejC`%| z%3S0X+r+iy$MTT-ecY}TUbrRl0m7SIpA()rFzWFW`N#XFemPUR-?8?+2JPiLK!2_C zO5yP7Asjx{!ZE*EBOE>hgu}T?2uHuI6b}C$!qI=Kg+t#b!E1!0UIT=~Czs%Zg-^`HrB*n6MkRP& zIQrp4;qYll@B(ogKSz1{O&5;ip;0*cUo-LU!DlBQmlg@{;k-roKF(W(!)KLnyq8}T z4xfzsS#>O)YTvF9ezl#E4|0%-Z zUl0!e>B2|*c4a8b7E7O}u(YjzznLx3OlE+up|A99zwB%CsrCMo7k%D2`YC+SubM?) z<3ZWni!E(>=j$Ub@$LP)t?d6cwWUq(^Sph8XE%vD#0x#<;~GWZ?DGp4KcR2%`}WnM z&z3G~!h1j-FZ7LmeLqEblP9{;+XworS8kB-X6I;M=yCnuBKrI;vA#8)59n)ljeOL` zaSdMGBW_O@-ndufD}-nEi9GLlg->C>$Y%)8RY#8ZK%vL{+j`MA>>u@md|niKT%S)6 zUg_8EnAe5A;2nIa=zHa>Mb1eP6LGFc~-q}-0#m8 z-gs^-cZKl6n8^G4IEQ#JUo=BF=2g}R$Nb449~a?+d9B&PG5^!i@86-%Tpi;XDICu? zCoA_8)KcO3>!MHBZQ~mLHB;mEVBwg5$P33j!y4guuG)LMa(~QMEEQgJN7Uszm+LXl z*(4nErK^PFc|>17pP*iu`=T%Y-4Ad)mzgShyoWGDIOc6$6ps0&PCJyxkNK#f!ZCj} zQ#jt!=)GgPPu8C|O;X+*b+d(Io_U3EJh$!KrQ9FSwHFD`FOIs-JC*A(uQf>d8&Nky zIOfNe3CDa|PoL*QyHvj$edY%*5HGaalxE_UX%y`1=bl$re{uP5_Ya$95%=&7^9wr<8#m#?yrYs|PzGVI`twH&t5*&fOCB+PLMYe6 z2pjt!#9O^Hy+)irW=!4K5cSyeC)D*i=J-?g4dsnE&$rJRdttBqxbyRM<0e?V7GT|| zv(6qjY)l>J<^TD;GVEuUlzti1=2GL|e*C%(mA?3J*aodx?NYC%jl?g@#>NZP1|R3F z`x^1fn2dMl(mj)Lzl@AKho3dy#IJt(YvX=d*|yy?d^1nozt;C(g%hLiQR!=}_77jI z`~v`djr~85)oA-I;s>q?zp?L{zvI`&U3?gf8?J5J2wzTcrsWU!{qgtH*azieJ;L|5 zf|i-VTz|qUE0# z=!VKK`UKDPpU3^IJZnlV|F?lz`P%-C_A+5uYW@6L+6X@?@x|AdhxLZapVB2}6weK; zeCvx^{vQL|Q2Ci%WBD^Bu*#t4<(9Cqq4G!V70bu_4OYITQp>l~r~H z)d0T6{#efod_()U`u^Hp*v9(V#Qw#^{#I98uwD|rTlpGiX7?DspB`+N(h_Oh$H4ON z0V@goM_1pUnSEF7>cH$4O^=^S-(TZG-ptFEj=|78b^o02-|FYFk~sX({eLo#@TmzO zUiusm9dkZ@S^Mu0KG@&3ZP`%S#;XsHHErJAw!%DF_}GxB``c}zbkRV2h0ZZQL;{X5v literal 0 HcmV?d00001 diff --git a/t480s/dwm/dwm/dwm.png b/t480s/dwm/dwm/dwm.png new file mode 100644 index 0000000000000000000000000000000000000000..b1f9ba7e5f4cc7350ee2392ebcea5fcbe00fb49b GIT binary patch literal 373 zcmeAS@N?(olHy`uVBq!ia0vp^2Y@($g9*gC@m3f}u_bxCyDx`7I;J! zGca%iWx0hJ8D`Cq01C2~c>21sUt<^MF=V?Ztt9{yk}YwKC~?lu%}vcKVQ?-=O)N=G zQ7F$W$xsN%NL6t6^bL5QqM8R(c+=CxF{I+w+q;fj4F)_6j>`Z3pZ>_($QEQ&92OXP z%lpEKGwG8$G-U1H{@Y%;mx-mNK|p|siBVAj$Z~Mt-~h6K0!}~{PyozQ07(f5fTdVi zm=-zT`NweeJ#%S&{fequZGmkDDC*%x$$Sa*fAP=$`nJkhx1Y~k<8b2;Hq)FOdV=P$ q&oWzoxz_&nv&n0)xBzV8k*jsxheTIy&cCY600f?{elF{r5}E*x)opSB literal 0 HcmV?d00001 diff --git a/t480s/dwm/dwm/fibonacci.c b/t480s/dwm/dwm/fibonacci.c new file mode 100644 index 0000000..32cb89b --- /dev/null +++ b/t480s/dwm/dwm/fibonacci.c @@ -0,0 +1,66 @@ +void +fibonacci(Monitor *mon, int s) { + unsigned int i, n, nx, ny, nw, nh; + Client *c; + + for(n = 0, c = nexttiled(mon->clients); c; c = nexttiled(c->next), n++); + if(n == 0) + return; + + nx = mon->wx; + ny = 0; + nw = mon->ww; + nh = mon->wh; + + for(i = 0, c = nexttiled(mon->clients); c; c = nexttiled(c->next)) { + if((i % 2 && nh / 2 > 2 * c->bw) + || (!(i % 2) && nw / 2 > 2 * c->bw)) { + if(i < n - 1) { + if(i % 2) + nh /= 2; + else + nw /= 2; + if((i % 4) == 2 && !s) + nx += nw; + else if((i % 4) == 3 && !s) + ny += nh; + } + if((i % 4) == 0) { + if(s) + ny += nh; + else + ny -= nh; + } + else if((i % 4) == 1) + nx += nw; + else if((i % 4) == 2) + ny += nh; + else if((i % 4) == 3) { + if(s) + nx += nw; + else + nx -= nw; + } + if(i == 0) + { + if(n != 1) + nw = mon->ww * mon->mfact; + ny = mon->wy; + } + else if(i == 1) + nw = mon->ww - nw; + i++; + } + resize(c, nx, ny, nw - 2 * c->bw, nh - 2 * c->bw, False); + } +} + +void +dwindle(Monitor *mon) { + fibonacci(mon, 1); +} + +void +spiral(Monitor *mon) { + fibonacci(mon, 0); +} diff --git a/t480s/dwm/dwm/functions.h b/t480s/dwm/dwm/functions.h new file mode 100644 index 0000000..1f62163 --- /dev/null +++ b/t480s/dwm/dwm/functions.h @@ -0,0 +1,30 @@ +/* Key binding functions */ +static void defaultgaps(const Arg *arg); +static void incrgaps(const Arg *arg); +static void incrigaps(const Arg *arg); +static void incrogaps(const Arg *arg); +static void incrohgaps(const Arg *arg); +static void incrovgaps(const Arg *arg); +static void incrihgaps(const Arg *arg); +static void incrivgaps(const Arg *arg); +static void togglegaps(const Arg *arg); +/* Layouts (delete the ones you do not need) */ +static void bstack(Monitor *m); +static void bstackhoriz(Monitor *m); +static void centeredmaster(Monitor *m); +static void centeredfloatingmaster(Monitor *m); +static void deck(Monitor *m); +static void dwindle(Monitor *m); +static void fibonacci(Monitor *m, int s); +static void gaplessgrid(Monitor *m); +static void grid(Monitor *m); +static void horizgrid(Monitor *m); +static void nrowgrid(Monitor *m); +static void spiral(Monitor *m); +static void tile(Monitor *m); +/* Internals */ +static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc); +static void getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr); +static void setgaps(int oh, int ov, int ih, int iv); + +static void movestack(const Arg *arg); diff --git a/t480s/dwm/dwm/gaplessgrid.c b/t480s/dwm/dwm/gaplessgrid.c new file mode 100644 index 0000000..10808c5 --- /dev/null +++ b/t480s/dwm/dwm/gaplessgrid.c @@ -0,0 +1,35 @@ +void +gaplessgrid(Monitor *m) { + unsigned int n, cols, rows, cn, rn, i, cx, cy, cw, ch; + Client *c; + + for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) ; + if(n == 0) + return; + + /* grid dimensions */ + for(cols = 0; cols <= n/2; cols++) + if(cols*cols >= n) + break; + if(n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */ + cols = 2; + rows = n/cols; + + /* window geometries */ + cw = cols ? m->ww / cols : m->ww; + cn = 0; /* current column number */ + rn = 0; /* current row number */ + for(i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) { + if(i/rows + 1 > cols - n%cols) + rows = n/cols + 1; + ch = rows ? m->wh / rows : m->wh; + cx = m->wx + cn*cw; + cy = m->wy + rn*ch; + resize(c, cx, cy, cw - 2 * c->bw, ch - 2 * c->bw, False); + rn++; + if(rn >= rows) { + rn = 0; + cn++; + } + } +} diff --git a/t480s/dwm/dwm/movestack.c b/t480s/dwm/dwm/movestack.c new file mode 100644 index 0000000..c040462 --- /dev/null +++ b/t480s/dwm/dwm/movestack.c @@ -0,0 +1,49 @@ +void +movestack(const Arg *arg) { + Client *c = NULL, *p = NULL, *pc = NULL, *i; + + if(arg->i > 0) { + /* find the client after selmon->sel */ + for(c = selmon->sel->next; c && (!ISVISIBLE(c) || c->isfloating); c = c->next); + if(!c) + for(c = selmon->clients; c && (!ISVISIBLE(c) || c->isfloating); c = c->next); + + } + else { + /* find the client before selmon->sel */ + for(i = selmon->clients; i != selmon->sel; i = i->next) + if(ISVISIBLE(i) && !i->isfloating) + c = i; + if(!c) + for(; i; i = i->next) + if(ISVISIBLE(i) && !i->isfloating) + c = i; + } + /* find the client before selmon->sel and c */ + for(i = selmon->clients; i && (!p || !pc); i = i->next) { + if(i->next == selmon->sel) + p = i; + if(i->next == c) + pc = i; + } + + /* swap c and selmon->sel selmon->clients in the selmon->clients list */ + if(c && c != selmon->sel) { + Client *temp = selmon->sel->next==c?selmon->sel:selmon->sel->next; + selmon->sel->next = c->next==selmon->sel?c:c->next; + c->next = temp; + + if(p && p != c) + p->next = c; + if(pc && pc != selmon->sel) + pc->next = selmon->sel; + + if(selmon->sel == selmon->clients) + selmon->clients = c; + else if(c == selmon->clients) + selmon->clients = selmon->sel; + + arrange(selmon); + } +} + diff --git a/t480s/dwm/dwm/themes/catppuccin.h b/t480s/dwm/dwm/themes/catppuccin.h new file mode 100644 index 0000000..32eb291 --- /dev/null +++ b/t480s/dwm/dwm/themes/catppuccin.h @@ -0,0 +1,12 @@ +static const char black[] = "#1E1D2D"; +static const char gray2[] = "#282737"; // unfocused window border +static const char gray3[] = "#585767"; +static const char gray4[] = "#282737"; +static const char blue[] = "#96CDFB"; // focused window border +static const char green[] = "#ABE9B3"; +static const char red[] = "#F28FAD"; +static const char orange[] = "#F8BD96"; +static const char yellow[] = "#FAE3B0"; +static const char pink[] = "#d5aeea"; +static const char col_borderbar[] = "#1E1D2D"; // inner border +static const char white[] = "#f8f8f2"; \ No newline at end of file diff --git a/t480s/dwm/dwm/themes/dracula.h b/t480s/dwm/dwm/themes/dracula.h new file mode 100644 index 0000000..809cea0 --- /dev/null +++ b/t480s/dwm/dwm/themes/dracula.h @@ -0,0 +1,12 @@ +static const char black[] = "#21222C"; +static const char white[] = "#f8f8f2"; +static const char gray2[] = "#282a36"; // unfocused window border +static const char gray3[] = "#44475a"; +static const char gray4[] = "#282a36"; +static const char blue[] = "#bd93f9"; // focused window border +static const char green[] = "#50fa7b"; +static const char red[] = "#ff5555"; +static const char orange[] = "#ffb86c"; +static const char yellow[] = "#f1fa8c"; +static const char pink[] = "#ff79c6"; +static const char col_borderbar[] = "#21222c"; // inner border diff --git a/t480s/dwm/dwm/themes/gruvbox-dark.h b/t480s/dwm/dwm/themes/gruvbox-dark.h new file mode 100644 index 0000000..7c2e62f --- /dev/null +++ b/t480s/dwm/dwm/themes/gruvbox-dark.h @@ -0,0 +1,12 @@ +static const char black[] = "#1e2122"; +static const char white[] = "#c7b89d"; +static const char gray2[] = "#282b2c"; // unfocused window border +static const char gray3[] = "#5d6061"; +static const char gray4[] = "#282b2c"; +static const char blue[] = "#6f8faf"; // focused window border +static const char green[] = "#89b482"; +static const char red[] = "#ec6b64"; +static const char orange[] = "#d6b676"; +static const char yellow[] = "#d1b171"; +static const char pink[] = "#cc7f94"; +static const char col_borderbar[] = "#1e2122"; // inner border diff --git a/t480s/dwm/dwm/themes/nord.h b/t480s/dwm/dwm/themes/nord.h new file mode 100644 index 0000000..b9e5e59 --- /dev/null +++ b/t480s/dwm/dwm/themes/nord.h @@ -0,0 +1,12 @@ +static const char black[] = "#2A303C"; +static const char white[] = "#D8DEE9"; +static const char gray2[] = "#3B4252"; // unfocused window border +static const char gray3[] = "#606672"; +static const char gray4[] = "#6d8dad"; +static const char blue[] = "#81A1C1"; // focused window border +static const char green[] = "#89b482"; +static const char red[] = "#d57780"; +static const char orange[] = "#caaa6a"; +static const char yellow[] = "#EBCB8B"; +static const char pink[] = "#e39a83"; +static const char col_borderbar[] = "#2A303C"; // inner border diff --git a/t480s/dwm/dwm/themes/onedark.h b/t480s/dwm/dwm/themes/onedark.h new file mode 100644 index 0000000..7a3cafd --- /dev/null +++ b/t480s/dwm/dwm/themes/onedark.h @@ -0,0 +1,12 @@ +static const char black[] = "#1e222a"; +static const char white[] = "#abb2bf"; +static const char gray2[] = "#2e323a"; // unfocused window border +static const char gray3[] = "#545862"; +static const char gray4[] = "#6d8dad"; +static const char blue[] = "#61afef"; // focused window border +static const char green[] = "#7EC7A2"; +static const char red[] = "#e06c75"; +static const char orange[] = "#caaa6a"; +static const char yellow[] = "#EBCB8B"; +static const char pink[] = "#c678dd"; +static const char col_borderbar[] = "#1e222a"; // inner border diff --git a/t480s/dwm/dwm/transient.c b/t480s/dwm/dwm/transient.c new file mode 100644 index 0000000..040adb5 --- /dev/null +++ b/t480s/dwm/dwm/transient.c @@ -0,0 +1,42 @@ +/* cc transient.c -o transient -lX11 */ + +#include +#include +#include +#include + +int main(void) { + Display *d; + Window r, f, t = None; + XSizeHints h; + XEvent e; + + d = XOpenDisplay(NULL); + if (!d) + exit(1); + r = DefaultRootWindow(d); + + f = XCreateSimpleWindow(d, r, 100, 100, 400, 400, 0, 0, 0); + h.min_width = h.max_width = h.min_height = h.max_height = 400; + h.flags = PMinSize | PMaxSize; + XSetWMNormalHints(d, f, &h); + XStoreName(d, f, "floating"); + XMapWindow(d, f); + + XSelectInput(d, f, ExposureMask); + while (1) { + XNextEvent(d, &e); + + if (t == None) { + sleep(5); + t = XCreateSimpleWindow(d, r, 50, 50, 100, 100, 0, 0, 0); + XSetTransientForHint(d, t, f); + XStoreName(d, t, "transient"); + XMapWindow(d, t); + XSelectInput(d, t, ExposureMask); + } + } + + XCloseDisplay(d); + exit(0); +} diff --git a/t480s/dwm/dwm/util.c b/t480s/dwm/dwm/util.c new file mode 100644 index 0000000..96b82c9 --- /dev/null +++ b/t480s/dwm/dwm/util.c @@ -0,0 +1,36 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include + +#include "util.h" + +void +die(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + if (fmt[0] && fmt[strlen(fmt)-1] == ':') { + fputc(' ', stderr); + perror(NULL); + } else { + fputc('\n', stderr); + } + + exit(1); +} + +void * +ecalloc(size_t nmemb, size_t size) +{ + void *p; + + if (!(p = calloc(nmemb, size))) + die("calloc:"); + return p; +} diff --git a/t480s/dwm/dwm/util.h b/t480s/dwm/dwm/util.h new file mode 100644 index 0000000..f633b51 --- /dev/null +++ b/t480s/dwm/dwm/util.h @@ -0,0 +1,8 @@ +/* See LICENSE file for copyright and license details. */ + +#define MAX(A, B) ((A) > (B) ? (A) : (B)) +#define MIN(A, B) ((A) < (B) ? (A) : (B)) +#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B)) + +void die(const char *fmt, ...); +void *ecalloc(size_t nmemb, size_t size); diff --git a/t480s/dwm/dwm/util.o b/t480s/dwm/dwm/util.o new file mode 100644 index 0000000000000000000000000000000000000000..4e4cbdbfb7e2fb3466a10a752c9146dc9f0ae8b5 GIT binary patch literal 2264 zcmbuA&1(}u6u@8F)W+JTQA8>gy22_c=#r!erS&7V(T);I(F%I1X|idHX%aV6X{%tR z6&gyRe}D%M9t1sj@X&+MfFHf~C?Z-t3GGEs1%>$D?o2x@n~Oe}yf?r1F>hyfHV-c) zFW32eAjJpgVQ(fWz|Dp|J8qkC2to^7XXW4Q(e?%+R_1z`m522RD<}2tWI3V7lW4Jp z3cv7vr!%1s;crsEjlaWs5r3cPbC`$5GkwJ|Ug}RBVo3 z3R^md6JW~=`lg@(R{qYG6S~IAU)KG40P%W4_eX>~^aBl;>jmD*%3qzygZgR@Z)Zzq z$hFplKQ>>Z4X`cg(j)$(a@bMeo4p3U z>5#9zxiPSUeYYV$CVV@j`+}kQx~suW;p-N@4$_HWXs{_5=sO^whoY_U!_TUR3+g@I zlz<&5yWY!cLGzFjZ}*1mAdb*p*sev-;l+>F;NcqFsKL8xa6BrfPkL|^d!JDE;_&JR zruan8NQ05=k3eR^gc8q~mIe2+MQb9@vpBbMW*)M|DV_#%dV)g{{RIn5=iQ)1P-Y#4 z=kA>OpQ3a&M$@2MUwR! z#6D90%?dvvIMuILc)Jo$IkJw1HVMVkkaAWSyIkahQJR_LsZrG2a`d>gEHjrfxH-+i z$fS4*jL}jF468sB3Xd95Fw%v|Ni&Zj`2sf$yppF&Je9s9=41IOqi7ZIDESPgQbBWk zBx|K6P1)K1X${lqQRvK7iHk{xd`>ZUznksIY5(HFFV!M#Hi{FSf|+*{}SLH?71 zi*Q1=jJVd7+>KA6gKGY3K7AIcW(z C*C9>- literal 0 HcmV?d00001 diff --git a/t480s/dwm/dwm/vanitygaps.c b/t480s/dwm/dwm/vanitygaps.c new file mode 100644 index 0000000..1a7cee7 --- /dev/null +++ b/t480s/dwm/dwm/vanitygaps.c @@ -0,0 +1,795 @@ +/* Settings */ +#if !PERTAG_PATCH +static int enablegaps = 1; +#endif // PERTAG_PATCH + +void +setgaps(int oh, int ov, int ih, int iv) +{ + if (oh < 0) oh = 0; + if (ov < 0) ov = 0; + if (ih < 0) ih = 0; + if (iv < 0) iv = 0; + + selmon->gappoh = oh; + selmon->gappov = ov; + selmon->gappih = ih; + selmon->gappiv = iv; + arrange(selmon); +} + +void +togglegaps(const Arg *arg) +{ + #if PERTAG_PATCH + selmon->pertag->enablegaps[selmon->pertag->curtag] = !selmon->pertag->enablegaps[selmon->pertag->curtag]; + #else + enablegaps = !enablegaps; + #endif // PERTAG_PATCH + arrange(NULL); +} + +void +defaultgaps(const Arg *arg) +{ + setgaps(gappoh, gappov, gappih, gappiv); +} + +void +incrgaps(const Arg *arg) +{ + setgaps( + selmon->gappoh + arg->i, + selmon->gappov + arg->i, + selmon->gappih + arg->i, + selmon->gappiv + arg->i + ); +} + +void +incrigaps(const Arg *arg) +{ + setgaps( + selmon->gappoh, + selmon->gappov, + selmon->gappih + arg->i, + selmon->gappiv + arg->i + ); +} + +void +incrogaps(const Arg *arg) +{ + setgaps( + selmon->gappoh + arg->i, + selmon->gappov + arg->i, + selmon->gappih, + selmon->gappiv + ); +} + +void +incrohgaps(const Arg *arg) +{ + setgaps( + selmon->gappoh + arg->i, + selmon->gappov, + selmon->gappih, + selmon->gappiv + ); +} + +void +incrovgaps(const Arg *arg) +{ + setgaps( + selmon->gappoh, + selmon->gappov + arg->i, + selmon->gappih, + selmon->gappiv + ); +} + +void +incrihgaps(const Arg *arg) +{ + setgaps( + selmon->gappoh, + selmon->gappov, + selmon->gappih + arg->i, + selmon->gappiv + ); +} + +void +incrivgaps(const Arg *arg) +{ + setgaps( + selmon->gappoh, + selmon->gappov, + selmon->gappih, + selmon->gappiv + arg->i + ); +} + +void +getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc) +{ + unsigned int n, oe, ie; + #if PERTAG_PATCH + oe = ie = selmon->pertag->enablegaps[selmon->pertag->curtag]; + #else + oe = ie = enablegaps; + #endif // PERTAG_PATCH + Client *c; + + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + if (smartgaps && n == 1) { + oe = 0; // outer gaps disabled when only one client + } + + *oh = m->gappoh*oe; // outer horizontal gap + *ov = m->gappov*oe; // outer vertical gap + *ih = m->gappih*ie; // inner horizontal gap + *iv = m->gappiv*ie; // inner vertical gap + *nc = n; // number of clients +} + +void +getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr) +{ + unsigned int n; + float mfacts = 0, sfacts = 0; + int mtotal = 0, stotal = 0; + Client *c; + + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) + if (n < m->nmaster) + mfacts += c->cfact; + else + sfacts += c->cfact; + + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) + if (n < m->nmaster) + mtotal += msize * (c->cfact / mfacts); + else + stotal += ssize * (c->cfact / sfacts); + + *mf = mfacts; // total factor of master area + *sf = sfacts; // total factor of stack area + *mr = msize - mtotal; // the remainder (rest) of pixels after a cfacts master split + *sr = ssize - stotal; // the remainder (rest) of pixels after a cfacts stack split +} + +/*** + * Layouts + */ + +/* + * Bottomstack layout + gaps + * https://dwm.suckless.org/patches/bottomstack/ + */ +static void +bstack(Monitor *m) +{ + unsigned int i, n; + int oh, ov, ih, iv; + int mx = 0, my = 0, mh = 0, mw = 0; + int sx = 0, sy = 0, sh = 0, sw = 0; + float mfacts, sfacts; + int mrest, srest; + Client *c; + + getgaps(m, &oh, &ov, &ih, &iv, &n); + if (n == 0) + return; + + sx = mx = m->wx + ov; + sy = my = m->wy + oh; + sh = mh = m->wh - 2*oh; + mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1); + sw = m->ww - 2*ov - iv * (n - m->nmaster - 1); + + if (m->nmaster && n > m->nmaster) { + sh = (mh - ih) * (1 - m->mfact); + mh = mh - ih - sh; + sx = mx; + sy = my + mh + ih; + } + + getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest); + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { + if (i < m->nmaster) { + resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); + mx += WIDTH(c) + iv; + } else { + resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); + sx += WIDTH(c) + iv; + } + } +} + +static void +bstackhoriz(Monitor *m) +{ + unsigned int i, n; + int oh, ov, ih, iv; + int mx = 0, my = 0, mh = 0, mw = 0; + int sx = 0, sy = 0, sh = 0, sw = 0; + float mfacts, sfacts; + int mrest, srest; + Client *c; + + getgaps(m, &oh, &ov, &ih, &iv, &n); + if (n == 0) + return; + + sx = mx = m->wx + ov; + sy = my = m->wy + oh; + mh = m->wh - 2*oh; + sh = m->wh - 2*oh - ih * (n - m->nmaster - 1); + mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1); + sw = m->ww - 2*ov; + + if (m->nmaster && n > m->nmaster) { + sh = (mh - ih) * (1 - m->mfact); + mh = mh - ih - sh; + sy = my + mh + ih; + sh = m->wh - mh - 2*oh - ih * (n - m->nmaster); + } + + getfacts(m, mw, sh, &mfacts, &sfacts, &mrest, &srest); + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { + if (i < m->nmaster) { + resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); + mx += WIDTH(c) + iv; + } else { + resize(c, sx, sy, sw - (2*c->bw), sh * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0); + sy += HEIGHT(c) + ih; + } + } +} + +/* + * Centred master layout + gaps + * https://dwm.suckless.org/patches/centeredmaster/ + */ +void +centeredmaster(Monitor *m) +{ + unsigned int i, n; + int oh, ov, ih, iv; + int mx = 0, my = 0, mh = 0, mw = 0; + int lx = 0, ly = 0, lw = 0, lh = 0; + int rx = 0, ry = 0, rw = 0, rh = 0; + float mfacts = 0, lfacts = 0, rfacts = 0; + int mtotal = 0, ltotal = 0, rtotal = 0; + int mrest = 0, lrest = 0, rrest = 0; + Client *c; + + getgaps(m, &oh, &ov, &ih, &iv, &n); + if (n == 0) + return; + + /* initialize areas */ + mx = m->wx + ov; + my = m->wy + oh; + mh = m->wh - 2*oh - ih * ((!m->nmaster ? n : MIN(n, m->nmaster)) - 1); + mw = m->ww - 2*ov; + lh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - 1); + rh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - ((n - m->nmaster) % 2 ? 0 : 1)); + + if (m->nmaster && n > m->nmaster) { + /* go mfact box in the center if more than nmaster clients */ + if (n - m->nmaster > 1) { + /* ||<-S->|<---M--->|<-S->|| */ + mw = (m->ww - 2*ov - 2*iv) * m->mfact; + lw = (m->ww - mw - 2*ov - 2*iv) / 2; + rw = (m->ww - mw - 2*ov - 2*iv) - lw; + mx += lw + iv; + } else { + /* ||<---M--->|<-S->|| */ + mw = (mw - iv) * m->mfact; + lw = 0; + rw = m->ww - mw - iv - 2*ov; + } + lx = m->wx + ov; + ly = m->wy + oh; + rx = mx + mw + iv; + ry = m->wy + oh; + } + + /* calculate facts */ + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) { + if (!m->nmaster || n < m->nmaster) + mfacts += c->cfact; + else if ((n - m->nmaster) % 2) + lfacts += c->cfact; // total factor of left hand stack area + else + rfacts += c->cfact; // total factor of right hand stack area + } + + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) + if (!m->nmaster || n < m->nmaster) + mtotal += mh * (c->cfact / mfacts); + else if ((n - m->nmaster) % 2) + ltotal += lh * (c->cfact / lfacts); + else + rtotal += rh * (c->cfact / rfacts); + + mrest = mh - mtotal; + lrest = lh - ltotal; + rrest = rh - rtotal; + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { + if (!m->nmaster || i < m->nmaster) { + /* nmaster clients are stacked vertically, in the center of the screen */ + resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); + my += HEIGHT(c) + ih; + } else { + /* stack clients are stacked vertically */ + if ((i - m->nmaster) % 2 ) { + resize(c, lx, ly, lw - (2*c->bw), lh * (c->cfact / lfacts) + ((i - 2*m->nmaster) < 2*lrest ? 1 : 0) - (2*c->bw), 0); + ly += HEIGHT(c) + ih; + } else { + resize(c, rx, ry, rw - (2*c->bw), rh * (c->cfact / rfacts) + ((i - 2*m->nmaster) < 2*rrest ? 1 : 0) - (2*c->bw), 0); + ry += HEIGHT(c) + ih; + } + } + } +} + +void +centeredfloatingmaster(Monitor *m) +{ + unsigned int i, n; + float mfacts, sfacts; + float mivf = 1.0; // master inner vertical gap factor + int oh, ov, ih, iv, mrest, srest; + int mx = 0, my = 0, mh = 0, mw = 0; + int sx = 0, sy = 0, sh = 0, sw = 0; + Client *c; + + getgaps(m, &oh, &ov, &ih, &iv, &n); + if (n == 0) + return; + + sx = mx = m->wx + ov; + sy = my = m->wy + oh; + sh = mh = m->wh - 2*oh; + mw = m->ww - 2*ov - iv*(n - 1); + sw = m->ww - 2*ov - iv*(n - m->nmaster - 1); + + if (m->nmaster && n > m->nmaster) { + mivf = 0.8; + /* go mfact box in the center if more than nmaster clients */ + if (m->ww > m->wh) { + mw = m->ww * m->mfact - iv*mivf*(MIN(n, m->nmaster) - 1); + mh = m->wh * 0.9; + } else { + mw = m->ww * 0.9 - iv*mivf*(MIN(n, m->nmaster) - 1); + mh = m->wh * m->mfact; + } + mx = m->wx + (m->ww - mw) / 2; + my = m->wy + (m->wh - mh - 2*oh) / 2; + + sx = m->wx + ov; + sy = m->wy + oh; + sh = m->wh - 2*oh; + } + + getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest); + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i < m->nmaster) { + /* nmaster clients are stacked horizontally, in the center of the screen */ + resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); + mx += WIDTH(c) + iv*mivf; + } else { + /* stack clients are stacked horizontally */ + resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); + sx += WIDTH(c) + iv; + } +} + +/* + * Deck layout + gaps + * https://dwm.suckless.org/patches/deck/ + */ +void +deck(Monitor *m) +{ + unsigned int i, n; + int oh, ov, ih, iv; + int mx = 0, my = 0, mh = 0, mw = 0; + int sx = 0, sy = 0, sh = 0, sw = 0; + float mfacts, sfacts; + int mrest, srest; + Client *c; + + getgaps(m, &oh, &ov, &ih, &iv, &n); + if (n == 0) + return; + + sx = mx = m->wx + ov; + sy = my = m->wy + oh; + sh = mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1); + sw = mw = m->ww - 2*ov; + + if (m->nmaster && n > m->nmaster) { + sw = (mw - iv) * (1 - m->mfact); + mw = mw - iv - sw; + sx = mx + mw + iv; + sh = m->wh - 2*oh; + } + + getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest); + + if (n - m->nmaster > 0) /* override layout symbol */ + snprintf(m->ltsymbol, sizeof m->ltsymbol, "D %d", n - m->nmaster); + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i < m->nmaster) { + resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); + my += HEIGHT(c) + ih; + } else { + resize(c, sx, sy, sw - (2*c->bw), sh - (2*c->bw), 0); + } +} + +/* + * Fibonacci layout + gaps + * https://dwm.suckless.org/patches/fibonacci/ + */ +void +fibonacci(Monitor *m, int s) +{ + unsigned int i, n; + int nx, ny, nw, nh; + int oh, ov, ih, iv; + int nv, hrest = 0, wrest = 0, r = 1; + Client *c; + + getgaps(m, &oh, &ov, &ih, &iv, &n); + if (n == 0) + return; + + nx = m->wx + ov; + ny = m->wy + oh; + nw = m->ww - 2*ov; + nh = m->wh - 2*oh; + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) { + if (r) { + if ((i % 2 && (nh - ih) / 2 <= (bh + 2*c->bw)) + || (!(i % 2) && (nw - iv) / 2 <= (bh + 2*c->bw))) { + r = 0; + } + if (r && i < n - 1) { + if (i % 2) { + nv = (nh - ih) / 2; + hrest = nh - 2*nv - ih; + nh = nv; + } else { + nv = (nw - iv) / 2; + wrest = nw - 2*nv - iv; + nw = nv; + } + + if ((i % 4) == 2 && !s) + nx += nw + iv; + else if ((i % 4) == 3 && !s) + ny += nh + ih; + } + + if ((i % 4) == 0) { + if (s) { + ny += nh + ih; + nh += hrest; + } + else { + nh -= hrest; + ny -= nh + ih; + } + } + else if ((i % 4) == 1) { + nx += nw + iv; + nw += wrest; + } + else if ((i % 4) == 2) { + ny += nh + ih; + nh += hrest; + if (i < n - 1) + nw += wrest; + } + else if ((i % 4) == 3) { + if (s) { + nx += nw + iv; + nw -= wrest; + } else { + nw -= wrest; + nx -= nw + iv; + nh += hrest; + } + } + if (i == 0) { + if (n != 1) { + nw = (m->ww - iv - 2*ov) - (m->ww - iv - 2*ov) * (1 - m->mfact); + wrest = 0; + } + ny = m->wy + oh; + } + else if (i == 1) + nw = m->ww - nw - iv - 2*ov; + i++; + } + + resize(c, nx, ny, nw - (2*c->bw), nh - (2*c->bw), False); + } +} + +void +dwindle(Monitor *m) +{ + fibonacci(m, 1); +} + +void +spiral(Monitor *m) +{ + fibonacci(m, 0); +} + +/* + * Gappless grid layout + gaps (ironically) + * https://dwm.suckless.org/patches/gaplessgrid/ + */ +void +gaplessgrid(Monitor *m) +{ + unsigned int i, n; + int x, y, cols, rows, ch, cw, cn, rn, rrest, crest; // counters + int oh, ov, ih, iv; + Client *c; + + getgaps(m, &oh, &ov, &ih, &iv, &n); + if (n == 0) + return; + + /* grid dimensions */ + for (cols = 0; cols <= n/2; cols++) + if (cols*cols >= n) + break; + if (n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */ + cols = 2; + rows = n/cols; + cn = rn = 0; // reset column no, row no, client count + + ch = (m->wh - 2*oh - ih * (rows - 1)) / rows; + cw = (m->ww - 2*ov - iv * (cols - 1)) / cols; + rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows; + crest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols; + x = m->wx + ov; + y = m->wy + oh; + + for (i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) { + if (i/rows + 1 > cols - n%cols) { + rows = n/cols + 1; + ch = (m->wh - 2*oh - ih * (rows - 1)) / rows; + rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows; + } + resize(c, + x, + y + rn*(ch + ih) + MIN(rn, rrest), + cw + (cn < crest ? 1 : 0) - 2*c->bw, + ch + (rn < rrest ? 1 : 0) - 2*c->bw, + 0); + rn++; + if (rn >= rows) { + rn = 0; + x += cw + ih + (cn < crest ? 1 : 0); + cn++; + } + } +} + +/* + * Gridmode layout + gaps + * https://dwm.suckless.org/patches/gridmode/ + */ +void +grid(Monitor *m) +{ + unsigned int i, n; + int cx, cy, cw, ch, cc, cr, chrest, cwrest, cols, rows; + int oh, ov, ih, iv; + Client *c; + + getgaps(m, &oh, &ov, &ih, &iv, &n); + + /* grid dimensions */ + for (rows = 0; rows <= n/2; rows++) + if (rows*rows >= n) + break; + cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows; + + /* window geoms (cell height/width) */ + ch = (m->wh - 2*oh - ih * (rows - 1)) / (rows ? rows : 1); + cw = (m->ww - 2*ov - iv * (cols - 1)) / (cols ? cols : 1); + chrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows; + cwrest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols; + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { + cc = i / rows; + cr = i % rows; + cx = m->wx + ov + cc * (cw + iv) + MIN(cc, cwrest); + cy = m->wy + oh + cr * (ch + ih) + MIN(cr, chrest); + resize(c, cx, cy, cw + (cc < cwrest ? 1 : 0) - 2*c->bw, ch + (cr < chrest ? 1 : 0) - 2*c->bw, False); + } +} + +/* + * Horizontal grid layout + gaps + * https://dwm.suckless.org/patches/horizgrid/ + */ +void +horizgrid(Monitor *m) { + Client *c; + unsigned int n, i; + int oh, ov, ih, iv; + int mx = 0, my = 0, mh = 0, mw = 0; + int sx = 0, sy = 0, sh = 0, sw = 0; + int ntop, nbottom = 1; + float mfacts = 0, sfacts = 0; + int mrest, srest, mtotal = 0, stotal = 0; + + /* Count windows */ + getgaps(m, &oh, &ov, &ih, &iv, &n); + if (n == 0) + return; + + if (n <= 2) + ntop = n; + else { + ntop = n / 2; + nbottom = n - ntop; + } + sx = mx = m->wx + ov; + sy = my = m->wy + oh; + sh = mh = m->wh - 2*oh; + sw = mw = m->ww - 2*ov; + + if (n > ntop) { + sh = (mh - ih) / 2; + mh = mh - ih - sh; + sy = my + mh + ih; + mw = m->ww - 2*ov - iv * (ntop - 1); + sw = m->ww - 2*ov - iv * (nbottom - 1); + } + + /* calculate facts */ + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i < ntop) + mfacts += c->cfact; + else + sfacts += c->cfact; + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i < ntop) + mtotal += mh * (c->cfact / mfacts); + else + stotal += sw * (c->cfact / sfacts); + + mrest = mh - mtotal; + srest = sw - stotal; + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i < ntop) { + resize(c, mx, my, mw * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0); + mx += WIDTH(c) + iv; + } else { + resize(c, sx, sy, sw * (c->cfact / sfacts) + ((i - ntop) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0); + sx += WIDTH(c) + iv; + } +} + +/* + * nrowgrid layout + gaps + * https://dwm.suckless.org/patches/nrowgrid/ + */ +void +nrowgrid(Monitor *m) +{ + unsigned int n; + int ri = 0, ci = 0; /* counters */ + int oh, ov, ih, iv; /* vanitygap settings */ + unsigned int cx, cy, cw, ch; /* client geometry */ + unsigned int uw = 0, uh = 0, uc = 0; /* utilization trackers */ + unsigned int cols, rows = m->nmaster + 1; + Client *c; + + /* count clients */ + getgaps(m, &oh, &ov, &ih, &iv, &n); + + /* nothing to do here */ + if (n == 0) + return; + + /* force 2 clients to always split vertically */ + if (FORCE_VSPLIT && n == 2) + rows = 1; + + /* never allow empty rows */ + if (n < rows) + rows = n; + + /* define first row */ + cols = n / rows; + uc = cols; + cy = m->wy + oh; + ch = (m->wh - 2*oh - ih*(rows - 1)) / rows; + uh = ch; + + for (c = nexttiled(m->clients); c; c = nexttiled(c->next), ci++) { + if (ci == cols) { + uw = 0; + ci = 0; + ri++; + + /* next row */ + cols = (n - uc) / (rows - ri); + uc += cols; + cy = m->wy + oh + uh + ih; + uh += ch + ih; + } + + cx = m->wx + ov + uw; + cw = (m->ww - 2*ov - uw) / (cols - ci); + uw += cw + iv; + + resize(c, cx, cy, cw - (2*c->bw), ch - (2*c->bw), 0); + } +} + +/* + * Default tile layout + gaps + */ +static void +tile(Monitor *m) +{ + unsigned int i, n; + int oh, ov, ih, iv; + int mx = 0, my = 0, mh = 0, mw = 0; + int sx = 0, sy = 0, sh = 0, sw = 0; + float mfacts, sfacts; + int mrest, srest; + Client *c; + + getgaps(m, &oh, &ov, &ih, &iv, &n); + if (n == 0) + return; + + sx = mx = m->wx + ov; + sy = my = m->wy + oh; + mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1); + sh = m->wh - 2*oh - ih * (n - m->nmaster - 1); + sw = mw = m->ww - 2*ov; + + if (m->nmaster && n > m->nmaster) { + sw = (mw - iv) * (1 - m->mfact); + mw = mw - iv - sw; + sx = mx + mw + iv; + } + + getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest); + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i < m->nmaster) { + resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0); + my += HEIGHT(c) + ih; + } else { + resize(c, sx, sy, sw - (2*c->bw), sh * (c->cfact / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0); + sy += HEIGHT(c) + ih; + } +} diff --git a/t480s/dwm/rofi/config.rasi b/t480s/dwm/rofi/config.rasi new file mode 100644 index 0000000..bae4142 --- /dev/null +++ b/t480s/dwm/rofi/config.rasi @@ -0,0 +1,98 @@ +configuration{ + modi: "run,drun,window"; + lines: 5; + font: "Iosevka 12"; + show-icons: true; + icon-theme: "Paper Mono"; + terminal: "st"; + drun-display-format: "{icon} {name}"; + location: 0; + disable-history: false; + hide-scrollbar: true; + display-drun: "  Apps "; +} + +@theme "everblush" + +element-text, element-icon , mode-switcher { + background-color: inherit; + text-color: inherit; +} + +window { + height: 360px; + border: 3px; + border-color: @border-col; + background-color: @bg-col; +} + +mainbox { + background-color: @bg-col; +} + +inputbar { + children: [prompt,entry]; + background-color: @bg-col; + border-radius: 5px; + padding: 2px; +} + +prompt { + background-color: @blue; + padding: 6px; + text-color: @bg-col; + border-radius: 3px; + margin: 20px 0px 0px 20px; +} + +textbox-prompt-colon { + expand: false; + str: ":"; +} + +entry { + padding: 6px; + margin: 20px 0px 0px 10px; + text-color: @fg-col; + background-color: @bg-col; +} + +listview { + border: 0px 0px 0px; + padding: 6px 0px 0px; + margin: 10px 0px 0px 20px; + columns: 2; + background-color: @bg-col; +} + +element { + padding: 5px; + background-color: @bg-col; + text-color: @fg-col ; +} + +element-icon { + size: 25px; +} + +element selected { + background-color: @selected-col ; + text-color: @fg-col2 ; +} + +mode-switcher { + spacing: 0; + } + +button { + padding: 10px; + background-color: @bg-col-light; + text-color: @grey; + vertical-align: 0.5; + horizontal-align: 0.5; +} + +button selected { + background-color: @bg-col; + text-color: @blue; +} diff --git a/t480s/dwm/rofi/themes/dracula.rasi b/t480s/dwm/rofi/themes/dracula.rasi new file mode 100644 index 0000000..cc3fd9b --- /dev/null +++ b/t480s/dwm/rofi/themes/dracula.rasi @@ -0,0 +1,11 @@ +* { + bg-col: #282a36; + bg-col-light: #44475a; + border-col: #44475a; + selected-col: #44475a; + blue: #bd93f9; + fg-col: #f8f8f2; + fg-col2: #ffffff; + grey: #6272a4; + width: 600; +} diff --git a/t480s/dwm/rofi/themes/everblush.rasi b/t480s/dwm/rofi/themes/everblush.rasi new file mode 100644 index 0000000..0d5ab21 --- /dev/null +++ b/t480s/dwm/rofi/themes/everblush.rasi @@ -0,0 +1,11 @@ +* { + bg-col: #181f21; + bg-col-light: #22292b; + border-col: #272e30; + selected-col: #31383a; + blue: #67b0e8; + fg-col: #dadada; + fg-col2: #d5d5d5; + grey: #363d3f; + width: 600; +} diff --git a/t480s/dwm/rofi/themes/forest.rasi b/t480s/dwm/rofi/themes/forest.rasi new file mode 100644 index 0000000..8523049 --- /dev/null +++ b/t480s/dwm/rofi/themes/forest.rasi @@ -0,0 +1,11 @@ +* { + bg-col: #2B3339; + bg-col-light: #333b41; + border-col: #333b41; + selected-col: #333b41; + blue: #87c095; + fg-col: #b4bbc8; + fg-col2: #e67e80; + grey: #545c62; + width: 600; +} diff --git a/t480s/dwm/rofi/themes/gruv.rasi b/t480s/dwm/rofi/themes/gruv.rasi new file mode 100644 index 0000000..834e66c --- /dev/null +++ b/t480s/dwm/rofi/themes/gruv.rasi @@ -0,0 +1,11 @@ +* { + bg-col: #1e2122; + bg-col-light: #26292a; + border-col: #282b2c; + selected-col: #242728; + blue: #8dae88; + fg-col: #d4be98; + fg-col2: #df736d; + grey: #5b5e5f; + width: 600; +} diff --git a/t480s/dwm/rofi/themes/nord.rasi b/t480s/dwm/rofi/themes/nord.rasi new file mode 100644 index 0000000..a50eb45 --- /dev/null +++ b/t480s/dwm/rofi/themes/nord.rasi @@ -0,0 +1,11 @@ +* { + bg-col: #2E3440; + bg-col-light: #343a46; + border-col: #343a46; + selected-col: #343a46; + blue: #81A1C1; + fg-col: #b4bbc8; + fg-col2: #BF616A; + grey: #646a76; + width: 600; +} diff --git a/t480s/dwm/rofi/themes/onedark.rasi b/t480s/dwm/rofi/themes/onedark.rasi new file mode 100644 index 0000000..cb40d7c --- /dev/null +++ b/t480s/dwm/rofi/themes/onedark.rasi @@ -0,0 +1,11 @@ +* { + bg-col: #1e222a; + bg-col-light: #282c34; + border-col: #282c34; + selected-col: #282c34; + blue: #61afef; + fg-col: #abb2bf; + fg-col2: #e06c75; + grey: #565c64; + width: 600; +} diff --git a/t480s/dwm/scripts/bar.sh b/t480s/dwm/scripts/bar.sh new file mode 100755 index 0000000..ca222ed --- /dev/null +++ b/t480s/dwm/scripts/bar.sh @@ -0,0 +1,63 @@ +#!/bin/dash + +# ^c$var^ = fg color +# ^b$var^ = bg color + +interval=0 + +# load colors +. ~/.config/dwm/scripts/bar_themes/gruvbox-dark + +cpu() { + cpu_val=$(grep -o "^[^ ]*" /proc/loadavg) + + printf "^c$black^ ^b$green^ CPU" + printf "^c$white^ ^b$grey^ $cpu_val" +} + +pkg_updates() { + #updates=$(doas xbps-install -un | wc -l) # void + updates=$(checkupdates 2>/dev/null | wc -l) # arch + # updates=$(aptitude search '~U' | wc -l) # apt (ubuntu,debian etc) + + if [ -z "$updates" ]; then + printf " ^c$green^  Fully Updated" + else + printf " ^c$green^  $updates"" updates" + fi +} + +battery() { + get_capacity="$(cat /sys/class/power_supply/BAT1/capacity)" + printf "^c$blue^  $get_capacity" +} + +brightness() { + printf "^c$red^  " + printf "^c$red^%.0f\n" $(cat /sys/class/backlight/*/brightness) +} + +mem() { + printf "^c$blue^^b$black^  " + printf "^c$blue^ $(free -h | awk '/^Mem/ { print $3 }' | sed s/i//g)" +} + +wlan() { + case "$(cat /sys/class/net/wl*/operstate 2>/dev/null)" in + up) printf "^c$black^ ^b$blue^ 󰤨 ^d^%s" " ^c$blue^Connected" ;; + down) printf "^c$black^ ^b$blue^ 󰤭 ^d^%s" " ^c$blue^Disconnected" ;; + esac +} + +clock() { + printf "^c$black^ ^b$darkblue^ 󱑆 " + printf "^c$black^^b$blue^ $(date '+%H:%M') " +} + +while true; do + + [ $interval = 0 ] || [ $(($interval % 3600)) = 0 ] && updates=$(pkg_updates) + interval=$((interval + 1)) + + sleep 1 && xsetroot -name "$updates $(battery) $(brightness) $(cpu) $(mem) $(wlan) $(clock)" +done diff --git a/t480s/dwm/scripts/bar_themes/catppuccin b/t480s/dwm/scripts/bar_themes/catppuccin new file mode 100755 index 0000000..5f5b9fb --- /dev/null +++ b/t480s/dwm/scripts/bar_themes/catppuccin @@ -0,0 +1,11 @@ +#!/bin/dash + +# colors + +black=#1E1D2D +green=#ABE9B3 +white=#D9E0EE +grey=#282737 +blue=#96CDFB +red=#F28FAD +darkblue=#83bae8 diff --git a/t480s/dwm/scripts/bar_themes/dracula b/t480s/dwm/scripts/bar_themes/dracula new file mode 100755 index 0000000..ea2b4f4 --- /dev/null +++ b/t480s/dwm/scripts/bar_themes/dracula @@ -0,0 +1,11 @@ +#!/bin/dash + +# colors + +black=#21222c +green=#50fa7b +white=#f8f8f2 +grey=#282a36 +blue=#d6acff +red=#ff5555 +darkblue=#bd93f9 diff --git a/t480s/dwm/scripts/bar_themes/gruvbox-dark b/t480s/dwm/scripts/bar_themes/gruvbox-dark new file mode 100755 index 0000000..4999d0e --- /dev/null +++ b/t480s/dwm/scripts/bar_themes/gruvbox-dark @@ -0,0 +1,11 @@ +#!/bin/dash + +# colors + +black=#222526 +green=#89b482 +white=#c7b89d +grey=#2b2e2f +blue=#6f8faf +red=#ec6b64 +darkblue=#6080a0 diff --git a/t480s/dwm/scripts/bar_themes/nord b/t480s/dwm/scripts/bar_themes/nord new file mode 100755 index 0000000..d4a4415 --- /dev/null +++ b/t480s/dwm/scripts/bar_themes/nord @@ -0,0 +1,11 @@ +#!/bin/dash + +# colors + +black=#2E3440 +green=#A3BE8C +white=#D8DEE9 +grey=#373d49 +blue=#81A1C1 +red=#BF616A +darkblue=#7292b2 diff --git a/t480s/dwm/scripts/bar_themes/onedark b/t480s/dwm/scripts/bar_themes/onedark new file mode 100755 index 0000000..e2a42dd --- /dev/null +++ b/t480s/dwm/scripts/bar_themes/onedark @@ -0,0 +1,11 @@ +#!/bin/dash + +# colors + +black=#1e222a +green=#7eca9c +white=#abb2bf +grey=#282c34 +blue=#7aa2f7 +red=#d47d85 +darkblue=#668ee3 diff --git a/t480s/dwm/scripts/fetch b/t480s/dwm/scripts/fetch new file mode 100755 index 0000000..a0381e6 --- /dev/null +++ b/t480s/dwm/scripts/fetch @@ -0,0 +1,77 @@ +#!/bin/bash +clear +c=3 b=4 +for j in c b; do + for i in {0..7}; do + printf -v $j$i "%b" "\e[${!j}${i}m" + done +done + +user=$(whoami) +host=$(uname -a | awk '{print $2}') +memory=$(free -h) +os=$(source /etc/os-release && echo $PRETTY_NAME) +kernel=$(uname -sr) +wm="$(xprop -id $(xprop -root -notype | awk '$1=="_NET_SUPPORTING_WM_CHECK:"{print $5}') -notype -f _NET_WM_NAME 8t | grep "WM_NAME" | cut -f2 -d \")" +mem=$(free -m | sed -n 's/^Mem:\s\+[0-9]\+\s\+\([0-9]\+\)\s.\+/\1/p') +pkgs="$(xbps-query -l | wc -l)" +shell=$(echo "$SHELL" | awk -F/ '{for ( i=1; i <= NF; i++) sub(".", substr(toupper($i),1,1) , $i); print $NF}') +colors=$(for i in {0..7}; do echo -en "\e[${1}$((30 + $i))m▁▁▁"; done) + +get_uptime() { + # Uptime works by retrieving the data in total seconds and then + # converting that data into days, hours and minutes using simple + # math. + IFS=. read -r s _ /dev/null; do dwm && continue || break; done diff --git a/t480s/fish/config.fish b/t480s/fish/config.fish new file mode 100644 index 0000000..37afd25 --- /dev/null +++ b/t480s/fish/config.fish @@ -0,0 +1 @@ +set fish_greeting diff --git a/t480s/fish/fish_variables b/t480s/fish/fish_variables new file mode 100644 index 0000000..8681508 --- /dev/null +++ b/t480s/fish/fish_variables @@ -0,0 +1,35 @@ +# This file contains fish universal variable definitions. +# VERSION: 3.0 +SETUVAR __fish_initialized:3100 +SETUVAR _fish_abbr_apt:sudo\x20nala +SETUVAR _fish_abbr_fp:flatpak +SETUVAR _fish_abbr_nf:neofetch +SETUVAR fish_color_autosuggestion:555\x1ebrblack +SETUVAR fish_color_cancel:\x2dr +SETUVAR fish_color_command:005fd7 +SETUVAR fish_color_comment:990000 +SETUVAR fish_color_cwd:green +SETUVAR fish_color_cwd_root:red +SETUVAR fish_color_end:009900 +SETUVAR fish_color_error:ff0000 +SETUVAR fish_color_escape:00a6b2 +SETUVAR fish_color_history_current:\x2d\x2dbold +SETUVAR fish_color_host:normal +SETUVAR fish_color_host_remote:yellow +SETUVAR fish_color_match:\x2d\x2dbackground\x3dbrblue +SETUVAR fish_color_normal:normal +SETUVAR fish_color_operator:00a6b2 +SETUVAR fish_color_param:00afff +SETUVAR fish_color_quote:999900 +SETUVAR fish_color_redirection:00afff +SETUVAR fish_color_search_match:bryellow\x1e\x2d\x2dbackground\x3dbrblack +SETUVAR fish_color_selection:white\x1e\x2d\x2dbold\x1e\x2d\x2dbackground\x3dbrblack +SETUVAR fish_color_status:red +SETUVAR fish_color_user:brgreen +SETUVAR fish_color_valid_path:\x2d\x2dunderline +SETUVAR fish_greeting:\x1d +SETUVAR fish_key_bindings:fish_default_key_bindings +SETUVAR fish_pager_color_completion:\x1d +SETUVAR fish_pager_color_description:B3A06D\x1eyellow +SETUVAR fish_pager_color_prefix:white\x1e\x2d\x2dbold\x1e\x2d\x2dunderline +SETUVAR fish_pager_color_progress:brwhite\x1e\x2d\x2dbackground\x3dcyan diff --git a/t480s/fish/functions/fish_prompt.fish b/t480s/fish/functions/fish_prompt.fish new file mode 100644 index 0000000..20326a1 --- /dev/null +++ b/t480s/fish/functions/fish_prompt.fish @@ -0,0 +1,6 @@ +function fish_prompt + set_color $fish_color_cwd + echo -n (basename $PWD) + set_color normal + echo -n ' » ' +end diff --git a/t480s/kitty/kitty.conf b/t480s/kitty/kitty.conf new file mode 100644 index 0000000..89abd55 --- /dev/null +++ b/t480s/kitty/kitty.conf @@ -0,0 +1,59 @@ +font_family Noto Sans Mono +bold_font auto +italic_font auto +bold_italic_font auto + +font_size 13.0 + +# gruvbox-dark medium + +background #282828 +foreground #d4be98 + +selection_background #d4be98 +selection_foreground #282828 + +cursor #a89984 +cursor_text_color background + +active_tab_background #282828 +active_tab_foreground #d4be98 +active_tab_font_style bold +inactive_tab_background #282828 +inactive_tab_foreground #a89984 +inactive_tab_font_style normal + +# Black +color0 #665c54 +color8 #928374 + +# Red +color1 #ea6962 +color9 #ea6962 + +# Green +color2 #a9b665 +color10 #a9b665 + +# Yellow +color3 #e78a4e +color11 #d8a657 + +# Blue +color4 #7daea3 +color12 #7daea3 + +# Magenta +color5 #d3869b +color13 #d3869b + +# Cyan +color6 #89b482 +color14 #89b482 + +# White +color7 #d4be98 +color15 #d4be98 + +# vim:fileencoding=utf-8:ft=conf + diff --git a/t480s/nvim/.netrwhist b/t480s/nvim/.netrwhist new file mode 100644 index 0000000..edc0597 --- /dev/null +++ b/t480s/nvim/.netrwhist @@ -0,0 +1,6 @@ +let g:netrw_dirhistmax =10 +let g:netrw_dirhistcnt =4 +let g:netrw_dirhist_4='/home/pim/.config/neofetch' +let g:netrw_dirhist_3='/home/pim/.config/fish' +let g:netrw_dirhist_2='/home/pim/.config/kitty' +let g:netrw_dirhist_1='/home/pim/.config/polybar/material' diff --git a/t480s/nvim/init.vim b/t480s/nvim/init.vim new file mode 100644 index 0000000..4ee4cae --- /dev/null +++ b/t480s/nvim/init.vim @@ -0,0 +1,54 @@ +" ________ +" | _____ \ +" | | _/ / Pim Nelissen +" | | /__/ https://pim.wtf/ +" | | +" \_| + +" Neovim configuration file. + +" load all plugins. +call plug#begin('~/.local/share/nvim/plugged') +Plug 'vimsence/vimsence' +Plug 'lervag/vimtex' +Plug 'python-mode/python-mode' +Plug 'rust-lang/rust.vim' +Plug 'Gavinok/vim-troff' +Plug 'vim-airline/vim-airline' +Plug 'Yggdroot/indentLine' +Plug 'vim-airline/vim-airline-themes' +call plug#end() + +" configurations. +set number relativenumber +set tabstop=8 softtabstop=0 expandtab shiftwidth=4 smarttab +autocmd BufRead *.md set spell spelllang=en_uk +highlight LineNr ctermfg=8 + +" airline configuration. +let g:airline_theme='minimalist' +let g:airline_powerline_fonts=1 +let g:airline#extensions#tabline#enabled = 1 +let g:airline#extensions#wordcount#enabled=1 + +" vimtex configuration. +let g:tex_flavor='latex' +let g:vimtex_view_method='zathura' +let g:vimtex_quickfix_mode=0 +let g:vimtex_view_general_viewer='zathura' + +" ignore some dumb PEP8 warnings. +let g:pymode_lint_ignore="E501,W" +let g:pymode_lint_ignore="E302,W" + +" Set color of PEP8 line end column to grey. +autocmd BufRead *.py hi ColorColumn ctermbg=8 + +" other plugins configuration +let g:indentLine_leadingSpaceEnabled=1 +let g:indentLine_leadingSpaceChar = '⬞' +let g:indentLine_fileTypeExclude = ['tex', 'markdown'] + +" Custom commands +" Uses F4 to find and replace every instance of the word under the cursor. +nnoremap :%s///gc$F/i