diff --git a/.github/workflows/flake-update.yml b/.github/workflows/flake-update.yml index 6a570ab9..5b3811ab 100644 --- a/.github/workflows/flake-update.yml +++ b/.github/workflows/flake-update.yml @@ -14,9 +14,9 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: DeterminateSystems/nix-installer-action@v13 + - uses: DeterminateSystems/nix-installer-action@v14 - uses: DeterminateSystems/magic-nix-cache-action@v8 - - uses: DeterminateSystems/update-flake-lock@v23 + - uses: DeterminateSystems/update-flake-lock@v24 with: pr-title: "chore: update flake.lock" # Labels to be set on the PR diff --git a/.sops.yaml b/.sops.yaml deleted file mode 100644 index 8a9b32ca..00000000 --- a/.sops.yaml +++ /dev/null @@ -1,8 +0,0 @@ -keys: - - &host_sakotop age1nhj5fz9cakgd6rrkwpjkndra6fd4rqxgfvcrap5g0anwxgmh4yqspvf22y - -creation_rules: - - path_regex: hosts/sakotop/secrets/[^/]+\.(yaml|json|env|ini)$ - key_groups: - - age: - - *host_sakotop diff --git a/.sops.yaml~ b/.sops.yaml~ deleted file mode 100644 index e69de29b..00000000 diff --git a/README.md b/README.md index 91d8e491..11daeab8 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ + # My Dotfiles! [![built with nix](https://builtwithnix.org/badge.svg)](https://builtwithnix.org) @@ -5,14 +6,3 @@ TODO:: Make this better lmfao TODO::TODO:: Get markdown preview for emacs silly! - -## Credits - -[Misterio77/nix-starter-configs2](https://github.com/Misterio77/nix-starter-configs) -[pull request for a bug](https://github.com/Misterio77/nix-starter-configs/pull/34/commits/2a5f3ca3dde606b83ea30b5507347bf989819301)

-[doom emacs guy -> hlissner/dotfiles](https://github.com/hlissner/dotfiles)

-^ reason i found out about nixos

-[nixos.wiki (unofficial)](https://nixos.wiki/) -[colemickens/nixcfg](https://github.com/colemickens/nixcfg) -[NotAShelf](https://github.com/NotAShelf) - config really helps, also helped me setup nix for a couple of things -[Fsnkty](https://github.com/fsnkty) diff --git a/config/ags/config.js b/config/ags/config.js index 6b8e848b..5e3dc92b 100644 --- a/config/ags/config.js +++ b/config/ags/config.js @@ -15,20 +15,53 @@ const date = Variable("", { // so to make a reuseable widget, make it a function // then you can simply instantiate one by calling it -function Workspaces() { - const activeId = hyprland.active.workspace.bind("id") - const workspaces = hyprland.bind("workspaces") - .as(ws => ws.map(({ id }) => Widget.Button({ - on_clicked: () => hyprland.messageAsync(`dispatch workspace ${id}`), - child: Widget.Label(`${id}`), - class_name: activeId.as(i => `${i === id ? "focused" : ""}`), - }))) +// function Workspaces() { +// const activeId = hyprland.active.workspace.bind("id") +// const workspaces = hyprland.bind("workspaces") +// .as(ws => ws.map(({ id }) => Widget.Button({ +// on_clicked: () => hyprland.messageAsync(`dispatch workspace ${id}`), +// child: Widget.Label(`${id}`), +// class_name: activeId.as(i => `${i === id ? "focused" : ""}`), +// }))) - return Widget.Box({ - class_name: "workspaces", - children: workspaces, - }) -} +// return Widget.Box({ +// class_name: "workspaces", +// children: workspaces, +// }) +// } + +const dispatch = ws => hyprland.sendMessage(`dispatch workspace ${ws}`); + +export const Workspaces = () => Widget.EventBox({ + child: Widget.Box({ + children: Array.from({ length: 10 }, (_, i) => i + 1).map(i => Widget.Button({ + class_name: "workspace-buttons", + attribute: i, + // Keeps button from expanding to fit its container + onClicked: () => dispatch(i), + child: Widget.Box({ + class_name: "workspace-indicator", + // vpack: "start", + vpack: "center", + hpack: "center", + children: [ + Widget.Label({ + label: `${i}`, + justification: "center", + }) + ], + setup: self => self.hook(hyprland, () => { + // The "?" is used here to return "undefined" if the workspace doesn't exist + self.toggleClassName('workspace-inactive', (hyprland.getWorkspace(i)?.windows || 0) === 0); + self.toggleClassName('workspace-occupied', (hyprland.getWorkspace(i)?.windows || 0) > 0); + self.toggleClassName('workspace-active', hyprland.active.workspace.id === i); + // self.toggleClassName('workspace-large', (hyprland.getWorkspace(i)?.windows || 0) > 1); + }), + }), + + })), + }), +}); function ClientTitle() { @@ -128,22 +161,38 @@ function Volume() { function BatteryLabel() { - const value = battery.bind("percent").as(p => p > 0 ? p / 100 : 0) - const icon = battery.bind("percent").as(p => - `battery-level-${Math.floor(p / 10) * 10}-symbolic`) + const icons = { + 80: "full", + 50: "good", + 30: "low", + 10: "empty", + }; + const value = battery.bind("percent").as(p => p > 0 ? p / 100 : 0); + // const icon = battery.bind("percent").as(p => + // `battery-level-${Math.floor(p / 10) * 10}-symbolic`) - const percent = battery.bind("percent").as(x => x.toString()) + "%" + const percent = battery.bind("percent").as(x => x.toString()) + "%"; + + function getIcon() { + const icon = [80, 50, 30, 10].find(threshold => threshold <= battery.percent); + + return `battery-${icons[icon]}-symbolic`; + } + + const icon = Widget.Icon({ + icon: Utils.watch(getIcon(), battery, getIcon), + }); return Widget.Box({ class_name: "battery", visible: battery.bind("available"), children: [ - Widget.Icon({ icon }), + icon, Widget.Label({ label: battery.bind('percent').as(x => x.toString()), }) ], - }) + }); } @@ -168,7 +217,7 @@ function Left() { spacing: 8, children: [ Workspaces(), - ClientTitle(), + // ClientTitle(), ], }) } @@ -201,8 +250,8 @@ function Bar(monitor = 0) { name: `bar-${monitor}`, // name has to be unique class_name: "bar", monitor, - anchor: ["top", "left", "right"], - margins: [5, 10, 0, 10], + anchor: ["bottom", "left", "right"], + margins: [0, 10, 0, 10], exclusivity: "exclusive", child: Widget.CenterBox({ start_widget: Left(), diff --git a/config/ags/style.css b/config/ags/style.css index c099733a..c3bdc75e 100644 --- a/config/ags/style.css +++ b/config/ags/style.css @@ -3,43 +3,69 @@ } window.bar { - background-color: @theme_bg_color; + /* background-color: @theme_bg_color; */ + background: rgba(0, 0, 0, .1); color: @theme_fg_color; + min-height: 10rem; + border: 2px solid #ea4c88; + border-bottom: none; + border-radius: 6px 6px 0px 0px; } button { min-width: 0; - padding-top: 0; - padding-bottom: 0; - border: none; + /* padding-top: 0; + padding-bottom: 0; */ background-color: transparent; - border-bottom: 3px solid transparent; + padding: 5px; + padding-left: 10px; + padding-right: 10px; + border: none; + background: none; } button:active { - background-color: @theme_selected_bg_color; + background-color: #ea4c88; } button:hover { - border-bottom: 3px solid @theme_fg_color; + /* border-bottom: 1px solid @theme_fg_color; */ } label { font-weight: bold; } -.workspaces button.focused { - border-bottom: 3px solid @theme_selected_bg_color; -} - .client-title { - color: @theme_selected_bg_color; + color: #ea4c88; } .notification { color: yellow; } +.workspace-indicator { + min-width: 0; + padding-top: 0; + padding-bottom: 0; + margin: 0; + background-color: transparent; + padding-bottom: 2px; +} + +.workspace-inactive { + opacity: 0.5; +} + +.workspace-occupied { + opacity: 1; +} + +.workspace-active { + border-bottom: 2px solid #ea4c88; + padding-bottom: 0; +} + levelbar block, highlight { min-height: 10px; diff --git a/config/background.png b/config/background.png index 3c363c58..2e06a508 100644 Binary files a/config/background.png and b/config/background.png differ diff --git a/config/background5.png b/config/background5.png new file mode 100644 index 00000000..3c363c58 Binary files /dev/null and b/config/background5.png differ diff --git a/config/dwm-old/LICENSE b/config/dwm-old/LICENSE deleted file mode 100644 index 995172fa..00000000 --- a/config/dwm-old/LICENSE +++ /dev/null @@ -1,38 +0,0 @@ -MIT/X Consortium License - -© 2006-2019 Anselm R Garbe -© 2006-2009 Jukka Salmi -© 2006-2007 Sander van Dijk -© 2007-2011 Peter Hartlich -© 2007-2009 Szabolcs Nagy -© 2007-2009 Christof Musik -© 2007-2009 Premysl Hruby -© 2007-2008 Enno Gottox Boland -© 2008 Martin Hurton -© 2008 Neale Pickett -© 2009 Mate Nagy -© 2010-2016 Hiltjo Posthuma -© 2010-2012 Connor Lane Smith -© 2011 Christoph Lohmann <20h@r-36.net> -© 2015-2016 Quentin Rameau -© 2015-2016 Eric Pruitt -© 2016-2017 Markus Teich -© 2020-2022 Chris Down - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/config/dwm-old/Makefile b/config/dwm-old/Makefile deleted file mode 100644 index 77bcbc02..00000000 --- a/config/dwm-old/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -# 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 - -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/config/dwm-old/README b/config/dwm-old/README deleted file mode 100644 index 95d4fd05..00000000 --- a/config/dwm-old/README +++ /dev/null @@ -1,48 +0,0 @@ -dwm - dynamic window manager -============================ -dwm is an extremely fast, small, and dynamic window manager for X. - - -Requirements ------------- -In order to build dwm you need the Xlib header files. - - -Installation ------------- -Edit config.mk to match your local setup (dwm is installed into -the /usr/local namespace by default). - -Afterwards enter the following command to build and install dwm (if -necessary as root): - - make clean install - - -Running dwm ------------ -Add the following line to your .xinitrc to start dwm using startx: - - exec dwm - -In order to connect dwm to a specific display, make sure that -the DISPLAY environment variable is set correctly, e.g.: - - DISPLAY=foo.bar:1 exec dwm - -(This will start dwm on display :1 of the host foo.bar.) - -In order to display status info in the bar, you can do something -like this in your .xinitrc: - - while xsetroot -name "`date` `uptime | sed 's/.*,//'`" - do - sleep 1 - done & - exec dwm - - -Configuration -------------- -The configuration of dwm is done by creating a custom config.h -and (re)compiling the source code. diff --git a/config/dwm-old/config.def.h b/config/dwm-old/config.def.h deleted file mode 100644 index 8a275dc8..00000000 --- a/config/dwm-old/config.def.h +++ /dev/null @@ -1,131 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* appearance */ -static const unsigned int borderpx = 1; /* border pixel of windows */ -static const unsigned int snap = 32; /* snap pixel */ -static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */ -static const unsigned int systrayonleft = 0; /* 0: systray in the right corner, >0: systray on left of status text */ -static const unsigned int systrayspacing = 2; /* systray spacing */ -static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/ -static const int showsystray = 1; /* 0 means no systray */ -static const int showbar = 1; /* 0 means no bar */ -static const int topbar = 1; /* 0 means bottom bar */ -static const char *fonts[] = { "JetBrainsMono NF:size=10" }; -static const char dmenufont[] = "monospace:size=10"; -// default colors -static const char col_gray1[] = "#222222"; -static const char col_gray2[] = "#444444"; -static const char col_gray3[] = "#bbbbbb"; -static const char col_gray4[] = "#eeeeee"; -static const char col_cyan[] = "#005577"; -// default colors -static const char *colors[][3] = { - /* fg bg border */ - [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, - [SchemeSel] = { col_gray4, col_cyan, col_cyan }, -}; - -static const char *const autostart[] = { - "picom", NULL, - "keepassxc", NULL, - "nm-applet", NULL, - "blueman-applet", NULL, - NULL /* terminate */ -}; - -/* tagging */ -static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - -static const Rule rules[] = { - /* xprop(1): - * WM_CLASS(STRING) = instance, class - * WM_NAME(STRING) = title - */ - /* class instance title tags mask isfloating monitor */ - { "Gimp", NULL, NULL, 0, 1, -1 }, - { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, -}; - -/* layout(s) */ -static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ -static const int nmaster = 1; /* number of clients in master area */ -static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ -static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ - -static const Layout layouts[] = { - /* symbol arrange function */ - { "[]=", tile }, /* first entry is default */ - { "><>", NULL }, /* no layout function means floating behavior */ - { "[M]", monocle }, -}; - -/* key definitions */ -#define MODKEY Mod4Mask -#define TAGKEYS(KEY,TAG) \ - { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ - { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ - { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ - { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, - -/* helper for spawning shell commands in the pre dwm-5.0 fashion */ -#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } - -/* commands */ -static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ -static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; -static const char *roficmd[] = { "rofi", "-show-icons", "-show", "drun", NULL }; -static const char *termcmd[] = { "kitty", NULL }; - -static const Key keys[] = { - /* modifier key function argument */ - { MODKEY, XK_space, spawn, {.v = roficmd } }, - { MODKEY, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY, XK_i, incnmaster, {.i = +1 } }, - { MODKEY, XK_d, incnmaster, {.i = -1 } }, - { MODKEY, XK_h, setmfact, {.f = -0.05} }, - { MODKEY, XK_l, setmfact, {.f = +0.05} }, - { MODKEY|ShiftMask, XK_Return, zoom, {0} }, - { MODKEY, XK_Tab, view, {0} }, - { MODKEY, XK_w, killclient, {0} }, - { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, - { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, - { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, - { MODKEY, XK_p, setlayout, {0} }, - { MODKEY|ShiftMask, XK_p, togglefloating, {0} }, - { MODKEY, XK_0, view, {.ui = ~0 } }, - { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, - { MODKEY, XK_comma, focusmon, {.i = -1 } }, - { MODKEY, XK_period, focusmon, {.i = +1 } }, - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, - { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, - TAGKEYS( XK_1, 0) - TAGKEYS( XK_2, 1) - TAGKEYS( XK_3, 2) - TAGKEYS( XK_4, 3) - TAGKEYS( XK_5, 4) - TAGKEYS( XK_6, 5) - TAGKEYS( XK_7, 6) - TAGKEYS( XK_8, 7) - TAGKEYS( XK_9, 8) - { MODKEY|ShiftMask, XK_q, quit, {0} }, -}; - -/* 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, {.v = termcmd } }, - { ClkClientWin, MODKEY, Button1, movemouse, {0} }, - { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, - { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, - { ClkTagBar, 0, Button1, view, {0} }, - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, -}; diff --git a/config/dwm-old/config.def.h.orig b/config/dwm-old/config.def.h.orig deleted file mode 100644 index 5b674f4b..00000000 --- a/config/dwm-old/config.def.h.orig +++ /dev/null @@ -1,123 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* appearance */ -static const unsigned int borderpx = 1; /* border pixel of windows */ -static const unsigned int snap = 32; /* snap pixel */ -static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */ -static const unsigned int systrayonleft = 0; /* 0: systray in the right corner, >0: systray on left of status text */ -static const unsigned int systrayspacing = 2; /* systray spacing */ -static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/ -static const int showsystray = 1; /* 0 means no systray */ -static const int showbar = 1; /* 0 means no bar */ -static const int topbar = 1; /* 0 means bottom bar */ -static const char *fonts[] = { "JetBrainsMono NF:size=10" }; -static const char dmenufont[] = "monospace:size=10"; -// default colors -static const char col_gray1[] = "#222222"; -static const char col_gray2[] = "#444444"; -static const char col_gray3[] = "#bbbbbb"; -static const char col_gray4[] = "#eeeeee"; -static const char col_cyan[] = "#005577"; -// default colors -static const char *colors[][3] = { - /* fg bg border */ - [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, - [SchemeSel] = { col_gray4, col_cyan, col_cyan }, -}; - -/* tagging */ -static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - -static const Rule rules[] = { - /* xprop(1): - * WM_CLASS(STRING) = instance, class - * WM_NAME(STRING) = title - */ - /* class instance title tags mask isfloating monitor */ - { "Gimp", NULL, NULL, 0, 1, -1 }, - { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, -}; - -/* layout(s) */ -static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ -static const int nmaster = 1; /* number of clients in master area */ -static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ -static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ - -static const Layout layouts[] = { - /* symbol arrange function */ - { "[]=", tile }, /* first entry is default */ - { "><>", NULL }, /* no layout function means floating behavior */ - { "[M]", monocle }, -}; - -/* key definitions */ -#define MODKEY Mod4Mask -#define TAGKEYS(KEY,TAG) \ - { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ - { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ - { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ - { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, - -/* helper for spawning shell commands in the pre dwm-5.0 fashion */ -#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } - -/* commands */ -static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ -static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; -static const char *roficmd[] = { "rofi", "-show-icons", "-show", "drun", NULL }; -static const char *termcmd[] = { "kitty", NULL }; - -static const Key keys[] = { - /* modifier key function argument */ - { MODKEY, XK_space, spawn, {.v = roficmd } }, - { MODKEY, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY, XK_i, incnmaster, {.i = +1 } }, - { MODKEY, XK_d, incnmaster, {.i = -1 } }, - { MODKEY, XK_h, setmfact, {.f = -0.05} }, - { MODKEY, XK_l, setmfact, {.f = +0.05} }, - { MODKEY|ShiftMask, XK_Return, zoom, {0} }, - { MODKEY, XK_Tab, view, {0} }, - { MODKEY|ShiftMask, XK_c, killclient, {0} }, - { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, - { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, - { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, - { MODKEY, XK_p, setlayout, {0} }, - { MODKEY|ShiftMask, XK_p, togglefloating, {0} }, - { MODKEY, XK_0, view, {.ui = ~0 } }, - { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, - { MODKEY, XK_comma, focusmon, {.i = -1 } }, - { MODKEY, XK_period, focusmon, {.i = +1 } }, - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, - { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, - TAGKEYS( XK_1, 0) - TAGKEYS( XK_2, 1) - TAGKEYS( XK_3, 2) - TAGKEYS( XK_4, 3) - TAGKEYS( XK_5, 4) - TAGKEYS( XK_6, 5) - TAGKEYS( XK_7, 6) - TAGKEYS( XK_8, 7) - TAGKEYS( XK_9, 8) - { MODKEY|ShiftMask, XK_q, quit, {0} }, -}; - -/* 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, {.v = termcmd } }, - { ClkClientWin, MODKEY, Button1, movemouse, {0} }, - { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, - { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, - { ClkTagBar, 0, Button1, view, {0} }, - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, -}; diff --git a/config/dwm-old/config.mk b/config/dwm-old/config.mk deleted file mode 100644 index ba64d3d1..00000000 --- a/config/dwm-old/config.mk +++ /dev/null @@ -1,39 +0,0 @@ -# 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} - -# flags -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} -CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} -LDFLAGS = ${LIBS} - -# Solaris -#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" -#LDFLAGS = ${LIBS} - -# compiler and linker -CC = cc diff --git a/config/dwm-old/drw.c b/config/dwm-old/drw.c deleted file mode 100644 index a58a2b48..00000000 --- a/config/dwm-old/drw.c +++ /dev/null @@ -1,450 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#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->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->drawable) - XFreePixmap(drw->dpy, drw->drawable); - drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); -} - -void -drw_free(Drw *drw) -{ - XFreePixmap(drw->dpy, drw->drawable); - XFreeGC(drw->dpy, drw->gc); - drw_fontset_free(drw->fonts); - free(drw); -} - -/* This function is an implementation detail. Library users should use - * drw_fontset_create instead. - */ -static Fnt * -xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) -{ - Fnt *font; - XftFont *xfont = NULL; - FcPattern *pattern = NULL; - - if (fontname) { - /* Using the pattern found at font->xfont->pattern does not yield the - * same substitution results as using the pattern returned by - * FcNameParse; using the latter results in the desired fallback - * behaviour whereas the former just results in missing-character - * rectangles being drawn, at least with some fonts. */ - if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { - fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname); - return NULL; - } - if (!(pattern = FcNameParse((FcChar8 *) fontname))) { - fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname); - XftFontClose(drw->dpy, xfont); - return NULL; - } - } else if (fontpattern) { - if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { - fprintf(stderr, "error, cannot load font from pattern.\n"); - return NULL; - } - } else { - die("no font specified."); - } - - 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); -} - -/* 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; -} - -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_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/config/dwm-old/drw.h b/config/dwm-old/drw.h deleted file mode 100644 index 64714316..00000000 --- a/config/dwm-old/drw.h +++ /dev/null @@ -1,58 +0,0 @@ -/* 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; - 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); - -/* 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); - -/* Map functions */ -void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); diff --git a/config/dwm-old/dwm.1 b/config/dwm-old/dwm.1 deleted file mode 100644 index ddc8321f..00000000 --- a/config/dwm-old/dwm.1 +++ /dev/null @@ -1,176 +0,0 @@ -.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 -.BR dmenu(1) -for launching other programs. -.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\-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 -Quit 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 dmenu (1), -.BR st (1) -.SH ISSUES -Java applications which use the XToolkit/XAWT backend may draw grey windows -only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early -JDK 1.6 versions, because it assumes a reparenting window manager. Possible workarounds -are using JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or setting the -environment variable -.BR AWT_TOOLKIT=MToolkit -(to use the older Motif backend instead) or running -.B xprop -root -f _NET_WM_NAME 32a -set _NET_WM_NAME LG3D -or -.B wmname LG3D -(to pretend that a non-reparenting window manager is running that the -XToolkit/XAWT backend can recognize) or when using OpenJDK setting the environment variable -.BR _JAVA_AWT_WM_NONREPARENTING=1 . -.SH BUGS -Send all bug reports with a patch to hackers@suckless.org. diff --git a/config/dwm-old/dwm.c b/config/dwm-old/dwm.c deleted file mode 100644 index 380815a5..00000000 --- a/config/dwm-old/dwm.c +++ /dev/null @@ -1,2684 +0,0 @@ -/* 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 -#ifdef XINERAMA -#include -#endif /* XINERAMA */ -#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 ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) -#define LENGTH(X) (sizeof X / sizeof X[0]) -#define MOUSEMASK (BUTTONMASK|PointerMotionMask) -#define WIDTH(X) ((X)->w + 2 * (X)->bw) -#define HEIGHT(X) ((X)->h + 2 * (X)->bw) -#define TAGMASK ((1 << LENGTH(tags)) - 1) -#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) - -#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, CurLast }; /* cursor */ -enum { SchemeNorm, SchemeSel }; /* color schemes */ -enum { NetSupported, NetWMName, NetWMState, NetWMCheck, - NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ -enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */ -enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ -enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, - ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ - -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; - 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, isfloating, isurgent, neverfocus, oldstate, isfullscreen; - 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; - -struct Monitor { - char ltsymbol[16]; - float mfact; - int nmaster; - int num; - int by; /* bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; - int showbar; - int topbar; - Client *clients; - Client *sel; - Client *stack; - Monitor *next; - Window barwin; - const Layout *lt[2]; -}; - -typedef struct { - const char *class; - const char *instance; - const char *title; - unsigned int tags; - int isfloating; - int monitor; -} Rule; - -typedef struct Systray Systray; -struct Systray { - Window win; - Client *icons; -}; - -/* 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 destroynotify(XEvent *e); -static void detach(Client *c); -static void detachstack(Client *c); -static Monitor *dirtomon(int dir); -static void drawbar(Monitor *m); -static void drawbars(void); -static int drawstatusbar(Monitor *m, int bh, char* text); -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 Atom getatomprop(Client *c, Atom prop); -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 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 Client *nexttiled(Client *c); -static void pop(Client *c); -static void propertynotify(XEvent *e); -static void quit(const Arg *arg); -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 setclientstate(Client *c, long state); -static void setfocus(Client *c); -static void setfullscreen(Client *c, int fullscreen); -static void setlayout(const Arg *arg); -static void setmfact(const Arg *arg); -static void setup(void); -static void seturgent(Client *c, int urg); -static void showhide(Client *c); -static void spawn(const Arg *arg); -static Monitor *systraytomon(Monitor *m); -static void tag(const Arg *arg); -static void tagmon(const Arg *arg); -static void tile(Monitor *m); -static void togglebar(const Arg *arg); -static void togglefloating(const Arg *arg); -static void toggletag(const Arg *arg); -static void toggleview(const Arg *arg); -static void unfocus(Client *c, int setfocus); -static void unmanage(Client *c, int destroyed); -static void unmapnotify(XEvent *e); -static void updatebarpos(Monitor *m); -static void updatebars(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 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); -static void autostart_exec(void); - -/* 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 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; -static Display *dpy; -static Drw *drw; -static Monitor *mons, *selmon; -static Window root, wmcheckwin; - -/* configuration, allows nested code to access above variables */ -#include "config.h" - -/* compile-time check if all tags fit into an unsigned int bit array. */ -struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; - -/* dwm will keep pid's of processes from autostart array and kill them at quit */ -static pid_t *autostart_pids; -static size_t autostart_len; - -/* execute command from autostart array */ -static void -autostart_exec() { - const char *const *p; - // https://github.com/bakkeby/dwm-flexipatch/blob/master/patch/cool_autostart.c#L21 - struct sigaction sa; - size_t i = 0; - - /* count entries */ - for (p = autostart; *p; autostart_len++, p++) - while (*++p); - - autostart_pids = malloc(autostart_len * sizeof(pid_t)); - for (p = autostart; *p; i++, p++) { - if ((autostart_pids[i] = fork()) == 0) { - setsid(); - - // https://github.com/bakkeby/dwm-flexipatch/blob/master/patch/cool_autostart.c#L21 - /* Restore SIGCHLD sighandler to default before spawning a program */ - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = SIG_DFL; - sigaction(SIGCHLD, &sa, NULL); - - execvp(*p, (char *const *)p); - fprintf(stderr, "dwm: execvp %s\n", *p); - perror(" failed"); - _exit(EXIT_FAILURE); - } - /* skip arguments */ - while (*++p); - } -} - -/* function implementations */ -void -applyrules(Client *c) -{ - const char *class, *instance; - unsigned int i; - const Rule *r; - Monitor *m; - XClassHint ch = { NULL, NULL }; - - /* rule matching */ - 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->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) -{ - 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) -{ - 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; - 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) { - 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; - } else if (ev->x < x + TEXTW(selmon->ltsymbol)) - click = ClkLtSymbol; - else if (ev->x > selmon->ww - (int)TEXTW(stext) - getsystraywidth()) - click = ClkStatusText; - else - click = ClkWinTitle; - } else if ((c = wintoclient(ev->window))) { - focus(c); - restack(selmon); - XAllowEvents(dpy, ReplayPointer, CurrentTime); - click = ClkClientWin; - } - 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 && 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; - - if (mon == mons) - mons = mons->next; - else { - for (m = mons; m && m->next != mon; m = m->next); - m->next = mon->next; - } - XUnmapWindow(dpy, mon->barwin); - XDestroyWindow(dpy, mon->barwin); - 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); - 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; - - m = ecalloc(1, sizeof(Monitor)); - m->tagset[0] = m->tagset[1] = 1; - m->mfact = mfact; - m->nmaster = nmaster; - m->showbar = showbar; - m->topbar = topbar; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); - return m; -} - -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 += 2; /* 1px padding on both sides */ - ret = m->ww - 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, 0, w, bh, 1, 1); - x++; - - /* 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, 0, w, bh, 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, 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, 0, w, bh, 0, text, 0); - } - - drw_setscheme(drw, scheme[SchemeNorm]); - free(p); - - return ret; -} - -void -drawbar(Monitor *m) -{ - int x, w, tw = 0, stw = 0; - int boxs = drw->fonts->h / 9; - int boxw = drw->fonts->h / 6 + 2; - unsigned int i, occ = 0, urg = 0; - Client *c; - - if (!m->showbar) - return; - - if(showsystray && m == systraytomon(m) && !systrayonleft) - stw = getsystraywidth(); - - /* draw status first so it can be overdrawn by tags later */ - if (m == selmon) { /* status is only drawn on selected monitor */ - tw = m->ww - drawstatusbar(m, bh, stext); - } - - resizebarwin(m); - for (c = m->clients; c; c = c->next) { - occ |= c->tags; - if (c->isurgent) - urg |= c->tags; - } - x = 0; - for (i = 0; i < LENGTH(tags); i++) { - w = TEXTW(tags[i]); - drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); - if (occ & 1 << i) - drw_rect(drw, x + boxs, 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[SchemeNorm]); - x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); - - if ((w = m->ww - tw - stw - x) > bh) { - if (m->sel) { - drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); - if (m->sel->isfloating) - drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); - } else { - drw_setscheme(drw, scheme[SchemeNorm]); - drw_rect(drw, x, 0, w, bh, 1, 1); - } - } - drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh); -} - -void -drawbars(void) -{ - Monitor *m; - - for (m = mons; m; m = m->next) - drawbar(m); -} - -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)) - for (c = selmon->stack; c && !ISVISIBLE(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(); -} - -/* 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); c = c->next); - if (!c) - for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); - } else { - for (i = selmon->clients; i != selmon->sel; i = i->next) - if (ISVISIBLE(i)) - c = i; - if (!c) - for (; i; i = i->next) - if (ISVISIBLE(i)) - c = i; - } - 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, k; - unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; - int start, end, skip; - KeySym *syms; - - XUngrabKey(dpy, AnyKey, AnyModifier, root); - XDisplayKeycodes(dpy, &start, &end); - syms = XGetKeyboardMapping(dpy, start, end - start + 1, &skip); - if (!syms) - return; - for (k = start; k <= end; k++) - for (i = 0; i < LENGTH(keys); i++) - /* skip modifier codes, we do that ourselves */ - if (keys[i].keysym == syms[(k - start) * skip]) - for (j = 0; j < LENGTH(modifiers); j++) - XGrabKey(dpy, k, - keys[i].mod | modifiers[j], - root, True, - GrabModeAsync, GrabModeAsync); - XFree(syms); - } -} - -void -incnmaster(const Arg *arg) -{ - selmon->nmaster = 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; - - 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 = 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); - 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 */ - setclientstate(c, NormalState); - if (c->mon == selmon) - unfocus(selmon->sel, 0); - c->mon->sel = c; - arrange(c->mon); - 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); - for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) - resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); -} - -void -motionnotify(XEvent *e) -{ - static Monitor *mon = NULL; - Monitor *m; - XMotionEvent *ev = &e->xmotion; - - 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 -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)); c = c->next); - return c; -} - -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(); - break; - } - if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { - updatetitle(c); - if (c == c->mon->sel) - drawbar(c->mon); - } - if (ev->atom == netatom[NetWMWindowType]) - updatewindowtype(c); - } -} - -void -quit(const Arg *arg) -{ - size_t i; - - /* kill child processes */ - for (i = 0; i < autostart_len; i++) { - if (0 < autostart_pids[i]) { - kill(autostart_pids[i], SIGTERM); - waitpid(autostart_pids[i], NULL, 0); - } - } - - running = 0; -} - -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 = m->ww; - if (showsystray && m == systraytomon(m) && !systrayonleft) - w -= getsystraywidth(); - 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; - 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); - 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); - focus(NULL); - arrange(NULL); -} - -void -setclientstate(Client *c, long state) -{ - long data[] = { state, None }; - - XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32, - PropModeReplace, (unsigned char *)data, 2); -} - -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 -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 ^= 1; - if (arg && arg->v) - selmon->lt[selmon->sellt] = (Layout *)arg->v; - strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); - if (selmon->sel) - arrange(selmon); - else - drawbar(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 = f; - arrange(selmon); -} - -void -setup(void) -{ - int i; - XSetWindowAttributes wa; - Atom utf8string; - struct sigaction sa; - - /* do not transform children into zombies when they terminate */ - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT | SA_RESTART; - sa.sa_handler = SIG_IGN; - sigaction(SIGCHLD, &sa, NULL); - - /* clean up any zombies (inherited from .xinitrc etc) immediately */ - while (waitpid(-1, NULL, WNOHANG) > 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; - 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[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); - /* 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); - /* 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); - /* init system tray */ - updatesystray(); - /* init bars */ - updatebars(); - updatestatus(); - /* 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); - XDeleteProperty(dpy, root, netatom[NetClientList]); - /* 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 -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 -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 -spawn(const Arg *arg) -{ - struct sigaction sa; - - if (arg->v == dmenucmd) - dmenumon[0] = '0' + selmon->num; - if (fork() == 0) { - if (dpy) - close(ConnectionNumber(dpy)); - setsid(); - - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = SIG_DFL; - sigaction(SIGCHLD, &sa, NULL); - - execvp(((char **)arg->v)[0], (char **)arg->v); - die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]); - } -} - -void -tag(const Arg *arg) -{ - if (selmon->sel && arg->ui & TAGMASK) { - selmon->sel->tags = arg->ui & TAGMASK; - focus(NULL); - arrange(selmon); - } -} - -void -tagmon(const Arg *arg) -{ - if (!selmon->sel || !mons->next) - return; - sendmon(selmon->sel, dirtomon(arg->i)); -} - -void -tile(Monitor *m) -{ - unsigned int i, n, h, mw, my, ty; - Client *c; - - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - if (n == 0) - return; - - if (n > m->nmaster) - mw = m->nmaster ? m->ww * m->mfact : 0; - else - mw = m->ww; - for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if (i < m->nmaster) { - h = (m->wh - my) / (MIN(n, m->nmaster) - i); - resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); - if (my + HEIGHT(c) < m->wh) - my += HEIGHT(c); - } else { - h = (m->wh - ty) / (n - i); - resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); - if (ty + HEIGHT(c) < m->wh) - ty += HEIGHT(c); - } -} - -void -togglebar(const Arg *arg) -{ - selmon->showbar = !selmon->showbar; - updatebarpos(selmon); - resizebarwin(selmon); - if (showsystray) { - XWindowChanges wc; - if (!selmon->showbar) - wc.y = -bh; - else if (selmon->showbar) { - wc.y = 0; - if (!selmon->topbar) - wc.y = selmon->mh - bh; - } - 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 -toggletag(const Arg *arg) -{ - unsigned int newtags; - - if (!selmon->sel) - return; - newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); - if (newtags) { - selmon->sel->tags = newtags; - focus(NULL); - arrange(selmon); - } -} - -void -toggleview(const Arg *arg) -{ - unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); - - if (newtagset) { - selmon->tagset[selmon->seltags] = newtagset; - focus(NULL); - arrange(selmon); - } -} - -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); - 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 - }; - 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->by, w, 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); - XSetClassHint(dpy, m->barwin, &ch); - } -} - -void -updatebarpos(Monitor *m) -{ - m->wy = m->my; - m->wh = m->mh; - if (m->showbar) { - m->wh -= bh; - m->by = m->topbar ? m->wy : m->wy + m->wh; - m->wy = m->topbar ? m->wy + bh : m->wy; - } else - m->by = -bh; -} - -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); -} - -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) -{ - if (i) { - i->h = bh; - if (w == h) - i->w = bh; - else if (h == bh) - i->w = w; - else - i->w = (int) ((float)bh * ((float)w / (float)h)); - 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 > bh) { - if (i->w == i->h) - i->w = bh; - else - i->w = (int) ((float)bh * ((float)i->w / (float)i->h)); - i->h = bh; - } - } -} - -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 = m->mx + m->mw; - unsigned int sw = TEXTW(stext) - lrpad + systrayspacing; - unsigned int w = 1; - - if (!showsystray) - return; - if (systrayonleft) - x -= sw + lrpad / 2; - 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, 0, 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->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) -{ - if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ - if (arg->ui & TAGMASK) - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; - focus(NULL); - arrange(selmon); -} - -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) - 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) - 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"); - checkotherwm(); - autostart_exec(); - 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/config/dwm-old/dwm.c.orig b/config/dwm-old/dwm.c.orig deleted file mode 100644 index 01bbc3a4..00000000 --- a/config/dwm-old/dwm.c.orig +++ /dev/null @@ -1,2634 +0,0 @@ -/* 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 -#ifdef XINERAMA -#include -#endif /* XINERAMA */ -#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 ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) -#define LENGTH(X) (sizeof X / sizeof X[0]) -#define MOUSEMASK (BUTTONMASK|PointerMotionMask) -#define WIDTH(X) ((X)->w + 2 * (X)->bw) -#define HEIGHT(X) ((X)->h + 2 * (X)->bw) -#define TAGMASK ((1 << LENGTH(tags)) - 1) -#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) - -#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, CurLast }; /* cursor */ -enum { SchemeNorm, SchemeSel }; /* color schemes */ -enum { NetSupported, NetWMName, NetWMState, NetWMCheck, - NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ -enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */ -enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ -enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, - ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ - -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; - 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, isfloating, isurgent, neverfocus, oldstate, isfullscreen; - 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; - -struct Monitor { - char ltsymbol[16]; - float mfact; - int nmaster; - int num; - int by; /* bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; - int showbar; - int topbar; - Client *clients; - Client *sel; - Client *stack; - Monitor *next; - Window barwin; - const Layout *lt[2]; -}; - -typedef struct { - const char *class; - const char *instance; - const char *title; - unsigned int tags; - int isfloating; - int monitor; -} Rule; - -typedef struct Systray Systray; -struct Systray { - Window win; - Client *icons; -}; - -/* 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 destroynotify(XEvent *e); -static void detach(Client *c); -static void detachstack(Client *c); -static Monitor *dirtomon(int dir); -static void drawbar(Monitor *m); -static void drawbars(void); -static int drawstatusbar(Monitor *m, int bh, char* text); -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 Atom getatomprop(Client *c, Atom prop); -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 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 Client *nexttiled(Client *c); -static void pop(Client *c); -static void propertynotify(XEvent *e); -static void quit(const Arg *arg); -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 setclientstate(Client *c, long state); -static void setfocus(Client *c); -static void setfullscreen(Client *c, int fullscreen); -static void setlayout(const Arg *arg); -static void setmfact(const Arg *arg); -static void setup(void); -static void seturgent(Client *c, int urg); -static void showhide(Client *c); -static void spawn(const Arg *arg); -static Monitor *systraytomon(Monitor *m); -static void tag(const Arg *arg); -static void tagmon(const Arg *arg); -static void tile(Monitor *m); -static void togglebar(const Arg *arg); -static void togglefloating(const Arg *arg); -static void toggletag(const Arg *arg); -static void toggleview(const Arg *arg); -static void unfocus(Client *c, int setfocus); -static void unmanage(Client *c, int destroyed); -static void unmapnotify(XEvent *e); -static void updatebarpos(Monitor *m); -static void updatebars(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 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 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; -static Display *dpy; -static Drw *drw; -static Monitor *mons, *selmon; -static Window root, wmcheckwin; - -/* configuration, allows nested code to access above variables */ -#include "config.h" - -/* 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->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->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) -{ - 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) -{ - 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; - 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) { - 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; - } else if (ev->x < x + TEXTW(selmon->ltsymbol)) - click = ClkLtSymbol; - else if (ev->x > selmon->ww - (int)TEXTW(stext) - getsystraywidth()) - click = ClkStatusText; - else - click = ClkWinTitle; - } else if ((c = wintoclient(ev->window))) { - focus(c); - restack(selmon); - XAllowEvents(dpy, ReplayPointer, CurrentTime); - click = ClkClientWin; - } - 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 && 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; - - if (mon == mons) - mons = mons->next; - else { - for (m = mons; m && m->next != mon; m = m->next); - m->next = mon->next; - } - XUnmapWindow(dpy, mon->barwin); - XDestroyWindow(dpy, mon->barwin); - 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); - 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; - - m = ecalloc(1, sizeof(Monitor)); - m->tagset[0] = m->tagset[1] = 1; - m->mfact = mfact; - m->nmaster = nmaster; - m->showbar = showbar; - m->topbar = topbar; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); - return m; -} - -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 += 2; /* 1px padding on both sides */ - ret = m->ww - 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, 0, w, bh, 1, 1); - x++; - - /* 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, 0, w, bh, 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, 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, 0, w, bh, 0, text, 0); - } - - drw_setscheme(drw, scheme[SchemeNorm]); - free(p); - - return ret; -} - -void -drawbar(Monitor *m) -{ - int x, w, tw = 0, stw = 0; - int boxs = drw->fonts->h / 9; - int boxw = drw->fonts->h / 6 + 2; - unsigned int i, occ = 0, urg = 0; - Client *c; - - if (!m->showbar) - return; - - if(showsystray && m == systraytomon(m) && !systrayonleft) - stw = getsystraywidth(); - - /* draw status first so it can be overdrawn by tags later */ - if (m == selmon) { /* status is only drawn on selected monitor */ - tw = m->ww - drawstatusbar(m, bh, stext); - } - - resizebarwin(m); - for (c = m->clients; c; c = c->next) { - occ |= c->tags; - if (c->isurgent) - urg |= c->tags; - } - x = 0; - for (i = 0; i < LENGTH(tags); i++) { - w = TEXTW(tags[i]); - drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); - if (occ & 1 << i) - drw_rect(drw, x + boxs, 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[SchemeNorm]); - x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); - - if ((w = m->ww - tw - stw - x) > bh) { - if (m->sel) { - drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); - if (m->sel->isfloating) - drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); - } else { - drw_setscheme(drw, scheme[SchemeNorm]); - drw_rect(drw, x, 0, w, bh, 1, 1); - } - } - drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh); -} - -void -drawbars(void) -{ - Monitor *m; - - for (m = mons; m; m = m->next) - drawbar(m); -} - -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)) - for (c = selmon->stack; c && !ISVISIBLE(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(); -} - -/* 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); c = c->next); - if (!c) - for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); - } else { - for (i = selmon->clients; i != selmon->sel; i = i->next) - if (ISVISIBLE(i)) - c = i; - if (!c) - for (; i; i = i->next) - if (ISVISIBLE(i)) - c = i; - } - 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, k; - unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; - int start, end, skip; - KeySym *syms; - - XUngrabKey(dpy, AnyKey, AnyModifier, root); - XDisplayKeycodes(dpy, &start, &end); - syms = XGetKeyboardMapping(dpy, start, end - start + 1, &skip); - if (!syms) - return; - for (k = start; k <= end; k++) - for (i = 0; i < LENGTH(keys); i++) - /* skip modifier codes, we do that ourselves */ - if (keys[i].keysym == syms[(k - start) * skip]) - for (j = 0; j < LENGTH(modifiers); j++) - XGrabKey(dpy, k, - keys[i].mod | modifiers[j], - root, True, - GrabModeAsync, GrabModeAsync); - XFree(syms); - } -} - -void -incnmaster(const Arg *arg) -{ - selmon->nmaster = 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; - - 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 = 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); - 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 */ - setclientstate(c, NormalState); - if (c->mon == selmon) - unfocus(selmon->sel, 0); - c->mon->sel = c; - arrange(c->mon); - 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); - for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) - resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); -} - -void -motionnotify(XEvent *e) -{ - static Monitor *mon = NULL; - Monitor *m; - XMotionEvent *ev = &e->xmotion; - - 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 -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)); c = c->next); - return c; -} - -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(); - break; - } - if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { - updatetitle(c); - if (c == c->mon->sel) - drawbar(c->mon); - } - if (ev->atom == netatom[NetWMWindowType]) - updatewindowtype(c); - } -} - -void -quit(const Arg *arg) -{ - running = 0; -} - -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 = m->ww; - if (showsystray && m == systraytomon(m) && !systrayonleft) - w -= getsystraywidth(); - 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; - 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); - 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); - focus(NULL); - arrange(NULL); -} - -void -setclientstate(Client *c, long state) -{ - long data[] = { state, None }; - - XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32, - PropModeReplace, (unsigned char *)data, 2); -} - -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 -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 ^= 1; - if (arg && arg->v) - selmon->lt[selmon->sellt] = (Layout *)arg->v; - strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); - if (selmon->sel) - arrange(selmon); - else - drawbar(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 = f; - arrange(selmon); -} - -void -setup(void) -{ - int i; - XSetWindowAttributes wa; - Atom utf8string; - struct sigaction sa; - - /* do not transform children into zombies when they terminate */ - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT | SA_RESTART; - sa.sa_handler = SIG_IGN; - sigaction(SIGCHLD, &sa, NULL); - - /* clean up any zombies (inherited from .xinitrc etc) immediately */ - while (waitpid(-1, NULL, WNOHANG) > 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; - 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[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); - /* 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); - /* 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); - /* init system tray */ - updatesystray(); - /* init bars */ - updatebars(); - updatestatus(); - /* 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); - XDeleteProperty(dpy, root, netatom[NetClientList]); - /* 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 -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 -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 -spawn(const Arg *arg) -{ - struct sigaction sa; - - if (arg->v == dmenucmd) - dmenumon[0] = '0' + selmon->num; - if (fork() == 0) { - if (dpy) - close(ConnectionNumber(dpy)); - setsid(); - - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = SIG_DFL; - sigaction(SIGCHLD, &sa, NULL); - - execvp(((char **)arg->v)[0], (char **)arg->v); - die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]); - } -} - -void -tag(const Arg *arg) -{ - if (selmon->sel && arg->ui & TAGMASK) { - selmon->sel->tags = arg->ui & TAGMASK; - focus(NULL); - arrange(selmon); - } -} - -void -tagmon(const Arg *arg) -{ - if (!selmon->sel || !mons->next) - return; - sendmon(selmon->sel, dirtomon(arg->i)); -} - -void -tile(Monitor *m) -{ - unsigned int i, n, h, mw, my, ty; - Client *c; - - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - if (n == 0) - return; - - if (n > m->nmaster) - mw = m->nmaster ? m->ww * m->mfact : 0; - else - mw = m->ww; - for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if (i < m->nmaster) { - h = (m->wh - my) / (MIN(n, m->nmaster) - i); - resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); - if (my + HEIGHT(c) < m->wh) - my += HEIGHT(c); - } else { - h = (m->wh - ty) / (n - i); - resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); - if (ty + HEIGHT(c) < m->wh) - ty += HEIGHT(c); - } -} - -void -togglebar(const Arg *arg) -{ - selmon->showbar = !selmon->showbar; - updatebarpos(selmon); - resizebarwin(selmon); - if (showsystray) { - XWindowChanges wc; - if (!selmon->showbar) - wc.y = -bh; - else if (selmon->showbar) { - wc.y = 0; - if (!selmon->topbar) - wc.y = selmon->mh - bh; - } - 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 -toggletag(const Arg *arg) -{ - unsigned int newtags; - - if (!selmon->sel) - return; - newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); - if (newtags) { - selmon->sel->tags = newtags; - focus(NULL); - arrange(selmon); - } -} - -void -toggleview(const Arg *arg) -{ - unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); - - if (newtagset) { - selmon->tagset[selmon->seltags] = newtagset; - focus(NULL); - arrange(selmon); - } -} - -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); - 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 - }; - 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->by, w, 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); - XSetClassHint(dpy, m->barwin, &ch); - } -} - -void -updatebarpos(Monitor *m) -{ - m->wy = m->my; - m->wh = m->mh; - if (m->showbar) { - m->wh -= bh; - m->by = m->topbar ? m->wy : m->wy + m->wh; - m->wy = m->topbar ? m->wy + bh : m->wy; - } else - m->by = -bh; -} - -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); -} - -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) -{ - if (i) { - i->h = bh; - if (w == h) - i->w = bh; - else if (h == bh) - i->w = w; - else - i->w = (int) ((float)bh * ((float)w / (float)h)); - 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 > bh) { - if (i->w == i->h) - i->w = bh; - else - i->w = (int) ((float)bh * ((float)i->w / (float)i->h)); - i->h = bh; - } - } -} - -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 = m->mx + m->mw; - unsigned int sw = TEXTW(stext) - lrpad + systrayspacing; - unsigned int w = 1; - - if (!showsystray) - return; - if (systrayonleft) - x -= sw + lrpad / 2; - 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, 0, 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->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) -{ - if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ - if (arg->ui & TAGMASK) - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; - focus(NULL); - arrange(selmon); -} - -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) - 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) - 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"); - 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/config/dwm-old/dwm.c.rej b/config/dwm-old/dwm.c.rej deleted file mode 100644 index e018d7d3..00000000 --- a/config/dwm-old/dwm.c.rej +++ /dev/null @@ -1,29 +0,0 @@ ---- dwm.c -+++ dwm.c -@@ -1671,9 +1710,25 @@ showhide(Client *c) - void - sigchld(int unused) - { -+ pid_t pid; -+ - if (signal(SIGCHLD, sigchld) == SIG_ERR) - die("can't install SIGCHLD handler:"); -- while (0 < waitpid(-1, NULL, WNOHANG)); -+ while (0 < (pid = waitpid(-1, NULL, WNOHANG))) { -+ pid_t *p, *lim; -+ -+ if (!(p = autostart_pids)) -+ continue; -+ lim = &p[autostart_len]; -+ -+ for (; p < lim; p++) { -+ if (*p == pid) { -+ *p = -1; -+ break; -+ } -+ } -+ -+ } - } - - void diff --git a/config/dwm-old/dwm.png b/config/dwm-old/dwm.png deleted file mode 100644 index b1f9ba7e..00000000 Binary files a/config/dwm-old/dwm.png and /dev/null differ diff --git a/config/dwm-old/transient.c b/config/dwm-old/transient.c deleted file mode 100644 index 040adb5b..00000000 --- a/config/dwm-old/transient.c +++ /dev/null @@ -1,42 +0,0 @@ -/* 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/config/dwm-old/util.c b/config/dwm-old/util.c deleted file mode 100644 index 96b82c98..00000000 --- a/config/dwm-old/util.c +++ /dev/null @@ -1,36 +0,0 @@ -/* 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/config/dwm-old/util.h b/config/dwm-old/util.h deleted file mode 100644 index f633b517..00000000 --- a/config/dwm-old/util.h +++ /dev/null @@ -1,8 +0,0 @@ -/* 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/config/dwm/LICENSE b/config/dwm/LICENSE deleted file mode 100644 index 995172fa..00000000 --- a/config/dwm/LICENSE +++ /dev/null @@ -1,38 +0,0 @@ -MIT/X Consortium License - -© 2006-2019 Anselm R Garbe -© 2006-2009 Jukka Salmi -© 2006-2007 Sander van Dijk -© 2007-2011 Peter Hartlich -© 2007-2009 Szabolcs Nagy -© 2007-2009 Christof Musik -© 2007-2009 Premysl Hruby -© 2007-2008 Enno Gottox Boland -© 2008 Martin Hurton -© 2008 Neale Pickett -© 2009 Mate Nagy -© 2010-2016 Hiltjo Posthuma -© 2010-2012 Connor Lane Smith -© 2011 Christoph Lohmann <20h@r-36.net> -© 2015-2016 Quentin Rameau -© 2015-2016 Eric Pruitt -© 2016-2017 Markus Teich -© 2020-2022 Chris Down - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/config/dwm/Makefile b/config/dwm/Makefile deleted file mode 100644 index ffa69b40..00000000 --- a/config/dwm/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -# 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: dwm - -.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 - -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 clean dist install uninstall diff --git a/config/dwm/README b/config/dwm/README deleted file mode 100644 index 95d4fd05..00000000 --- a/config/dwm/README +++ /dev/null @@ -1,48 +0,0 @@ -dwm - dynamic window manager -============================ -dwm is an extremely fast, small, and dynamic window manager for X. - - -Requirements ------------- -In order to build dwm you need the Xlib header files. - - -Installation ------------- -Edit config.mk to match your local setup (dwm is installed into -the /usr/local namespace by default). - -Afterwards enter the following command to build and install dwm (if -necessary as root): - - make clean install - - -Running dwm ------------ -Add the following line to your .xinitrc to start dwm using startx: - - exec dwm - -In order to connect dwm to a specific display, make sure that -the DISPLAY environment variable is set correctly, e.g.: - - DISPLAY=foo.bar:1 exec dwm - -(This will start dwm on display :1 of the host foo.bar.) - -In order to display status info in the bar, you can do something -like this in your .xinitrc: - - while xsetroot -name "`date` `uptime | sed 's/.*,//'`" - do - sleep 1 - done & - exec dwm - - -Configuration -------------- -The configuration of dwm is done by creating a custom config.h -and (re)compiling the source code. diff --git a/config/dwm/config.def.h b/config/dwm/config.def.h deleted file mode 100644 index 9efa7744..00000000 --- a/config/dwm/config.def.h +++ /dev/null @@ -1,116 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* appearance */ -static const unsigned int borderpx = 1; /* border pixel of windows */ -static const unsigned int snap = 32; /* snap pixel */ -static const int showbar = 1; /* 0 means no bar */ -static const int topbar = 1; /* 0 means bottom bar */ -static const char *fonts[] = { "monospace:size=10" }; -static const char dmenufont[] = "monospace:size=10"; -static const char col_gray1[] = "#222222"; -static const char col_gray2[] = "#444444"; -static const char col_gray3[] = "#bbbbbb"; -static const char col_gray4[] = "#eeeeee"; -static const char col_cyan[] = "#005577"; -static const char *colors[][3] = { - /* fg bg border */ - [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, - [SchemeSel] = { col_gray4, col_cyan, col_cyan }, -}; - -/* tagging */ -static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - -static const Rule rules[] = { - /* xprop(1): - * WM_CLASS(STRING) = instance, class - * WM_NAME(STRING) = title - */ - /* class instance title tags mask isfloating monitor */ - { "Gimp", NULL, NULL, 0, 1, -1 }, - { "Firefox", NULL, NULL, 1 << 8, 0, -1 }, -}; - -/* layout(s) */ -static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ -static const int nmaster = 1; /* number of clients in master area */ -static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ -static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ - -static const Layout layouts[] = { - /* symbol arrange function */ - { "[]=", tile }, /* first entry is default */ - { "><>", NULL }, /* no layout function means floating behavior */ - { "[M]", monocle }, -}; - -/* 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 char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ -static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; -static const char *termcmd[] = { "st", NULL }; - -static const Key keys[] = { - /* modifier key function argument */ - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY, XK_i, incnmaster, {.i = +1 } }, - { MODKEY, XK_d, incnmaster, {.i = -1 } }, - { MODKEY, XK_h, setmfact, {.f = -0.05} }, - { MODKEY, XK_l, setmfact, {.f = +0.05} }, - { MODKEY, XK_Return, zoom, {0} }, - { MODKEY, XK_Tab, view, {0} }, - { MODKEY|ShiftMask, XK_c, killclient, {0} }, - { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, - { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, - { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, - { MODKEY, XK_space, setlayout, {0} }, - { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, - { MODKEY, XK_0, view, {.ui = ~0 } }, - { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, - { MODKEY, XK_comma, focusmon, {.i = -1 } }, - { MODKEY, XK_period, focusmon, {.i = +1 } }, - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, - { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, - TAGKEYS( XK_1, 0) - TAGKEYS( XK_2, 1) - TAGKEYS( XK_3, 2) - TAGKEYS( XK_4, 3) - TAGKEYS( XK_5, 4) - TAGKEYS( XK_6, 5) - TAGKEYS( XK_7, 6) - TAGKEYS( XK_8, 7) - TAGKEYS( XK_9, 8) - { MODKEY|ShiftMask, XK_q, quit, {0} }, -}; - -/* 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, {.v = termcmd } }, - { ClkClientWin, MODKEY, Button1, movemouse, {0} }, - { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, - { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, - { ClkTagBar, 0, Button1, view, {0} }, - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, -}; - diff --git a/config/dwm/config.h b/config/dwm/config.h deleted file mode 100644 index 8ff5e516..00000000 --- a/config/dwm/config.h +++ /dev/null @@ -1,113 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* appearance */ -static const unsigned int borderpx = 1; /* border pixel of windows */ -static const unsigned int snap = 32; /* snap pixel */ -static const int showbar = 1; /* 0 means no bar */ -static const int topbar = 1; /* 0 means bottom bar */ -static const char *fonts[] = {"monospace:size=10"}; -static const char dmenufont[] = "monospace:size=10"; -static const char col_gray1[] = "#222222"; -static const char col_gray2[] = "#444444"; -static const char col_gray3[] = "#bbbbbb"; -static const char col_gray4[] = "#eeeeee"; -static const char col_cyan[] = "#005577"; -static const char *colors[][3] = { - /* fg bg border */ - [SchemeNorm] = {col_gray3, col_gray1, col_gray2}, - [SchemeSel] = {col_gray4, col_cyan, col_cyan}, -}; - -/* tagging */ -static const char *tags[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9"}; - -static const Rule rules[] = { - /* xprop(1): - * WM_CLASS(STRING) = instance, class - * WM_NAME(STRING) = title - */ - /* class instance title tags mask isfloating monitor */ - {"Gimp", NULL, NULL, 0, 1, -1}, - {"Firefox", NULL, NULL, 1 << 8, 0, -1}, -}; - -/* layout(s) */ -static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ -static const int nmaster = 1; /* number of clients in master area */ -static const int resizehints = - 1; /* 1 means respect size hints in tiled resizals */ -static const int lockfullscreen = - 1; /* 1 will force focus on the fullscreen window */ - -static const Layout layouts[] = { - /* symbol arrange function */ - {"[]=", tile}, /* first entry is default */ - {"><>", NULL}, /* no layout function means floating behavior */ - {"[M]", monocle}, -}; - -/* 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 char *roficmd[] = {"rofi", "-show", "drun", NULL}; -static const char *termcmd[] = {"wezterm", NULL}; - -static const Key keys[] = { - /* modifier key function argument */ - {MODKEY, XK_p, spawn, {.v = roficmd}}, - {MODKEY | ShiftMask, XK_Return, spawn, {.v = termcmd}}, - {MODKEY, XK_b, togglebar, {0}}, - {MODKEY, XK_j, focusstack, {.i = +1}}, - {MODKEY, XK_k, focusstack, {.i = -1}}, - {MODKEY, XK_i, incnmaster, {.i = +1}}, - {MODKEY, XK_d, incnmaster, {.i = -1}}, - {MODKEY, XK_h, setmfact, {.f = -0.05}}, - {MODKEY, XK_l, setmfact, {.f = +0.05}}, - {MODKEY, XK_Return, zoom, {0}}, - {MODKEY, XK_Tab, view, {0}}, - {MODKEY | ShiftMask, XK_c, killclient, {0}}, - {MODKEY, XK_t, setlayout, {.v = &layouts[0]}}, - {MODKEY, XK_f, setlayout, {.v = &layouts[1]}}, - {MODKEY, XK_m, setlayout, {.v = &layouts[2]}}, - {MODKEY, XK_space, setlayout, {0}}, - {MODKEY | ShiftMask, XK_space, togglefloating, {0}}, - {MODKEY, XK_0, view, {.ui = ~0}}, - {MODKEY | ShiftMask, XK_0, tag, {.ui = ~0}}, - {MODKEY, XK_comma, focusmon, {.i = -1}}, - {MODKEY, XK_period, focusmon, {.i = +1}}, - {MODKEY | ShiftMask, XK_comma, tagmon, {.i = -1}}, - {MODKEY | ShiftMask, XK_period, tagmon, {.i = +1}}, - TAGKEYS(XK_1, 0) TAGKEYS(XK_2, 1) TAGKEYS(XK_3, 2) TAGKEYS(XK_4, 3) - TAGKEYS(XK_5, 4) TAGKEYS(XK_6, 5) TAGKEYS(XK_7, 6) TAGKEYS(XK_8, 7) - TAGKEYS(XK_9, 8){MODKEY | ShiftMask, XK_q, quit, {0}}, -}; - -/* 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, {.v = termcmd}}, - {ClkClientWin, MODKEY, Button1, movemouse, {0}}, - {ClkClientWin, MODKEY, Button2, togglefloating, {0}}, - {ClkClientWin, MODKEY, Button3, resizemouse, {0}}, - {ClkTagBar, 0, Button1, view, {0}}, - {ClkTagBar, 0, Button3, toggleview, {0}}, - {ClkTagBar, MODKEY, Button1, tag, {0}}, - {ClkTagBar, MODKEY, Button3, toggletag, {0}}, -}; diff --git a/config/dwm/config.mk b/config/dwm/config.mk deleted file mode 100644 index 8efca9ad..00000000 --- a/config/dwm/config.mk +++ /dev/null @@ -1,39 +0,0 @@ -# dwm version -VERSION = 6.5 - -# 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} - -# flags -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} -CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} -LDFLAGS = ${LIBS} - -# Solaris -#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" -#LDFLAGS = ${LIBS} - -# compiler and linker -CC = cc diff --git a/config/dwm/drw.c b/config/dwm/drw.c deleted file mode 100644 index a58a2b48..00000000 --- a/config/dwm/drw.c +++ /dev/null @@ -1,450 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#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->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->drawable) - XFreePixmap(drw->dpy, drw->drawable); - drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen)); -} - -void -drw_free(Drw *drw) -{ - XFreePixmap(drw->dpy, drw->drawable); - XFreeGC(drw->dpy, drw->gc); - drw_fontset_free(drw->fonts); - free(drw); -} - -/* This function is an implementation detail. Library users should use - * drw_fontset_create instead. - */ -static Fnt * -xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) -{ - Fnt *font; - XftFont *xfont = NULL; - FcPattern *pattern = NULL; - - if (fontname) { - /* Using the pattern found at font->xfont->pattern does not yield the - * same substitution results as using the pattern returned by - * FcNameParse; using the latter results in the desired fallback - * behaviour whereas the former just results in missing-character - * rectangles being drawn, at least with some fonts. */ - if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { - fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname); - return NULL; - } - if (!(pattern = FcNameParse((FcChar8 *) fontname))) { - fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname); - XftFontClose(drw->dpy, xfont); - return NULL; - } - } else if (fontpattern) { - if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { - fprintf(stderr, "error, cannot load font from pattern.\n"); - return NULL; - } - } else { - die("no font specified."); - } - - 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); -} - -/* 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; -} - -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_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/config/dwm/drw.h b/config/dwm/drw.h deleted file mode 100644 index 64714316..00000000 --- a/config/dwm/drw.h +++ /dev/null @@ -1,58 +0,0 @@ -/* 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; - 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); - -/* 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); - -/* Map functions */ -void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h); diff --git a/config/dwm/dwm.1 b/config/dwm/dwm.1 deleted file mode 100644 index ddc8321f..00000000 --- a/config/dwm/dwm.1 +++ /dev/null @@ -1,176 +0,0 @@ -.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 -.BR dmenu(1) -for launching other programs. -.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\-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 -Quit 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 dmenu (1), -.BR st (1) -.SH ISSUES -Java applications which use the XToolkit/XAWT backend may draw grey windows -only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early -JDK 1.6 versions, because it assumes a reparenting window manager. Possible workarounds -are using JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or setting the -environment variable -.BR AWT_TOOLKIT=MToolkit -(to use the older Motif backend instead) or running -.B xprop -root -f _NET_WM_NAME 32a -set _NET_WM_NAME LG3D -or -.B wmname LG3D -(to pretend that a non-reparenting window manager is running that the -XToolkit/XAWT backend can recognize) or when using OpenJDK setting the environment variable -.BR _JAVA_AWT_WM_NONREPARENTING=1 . -.SH BUGS -Send all bug reports with a patch to hackers@suckless.org. diff --git a/config/dwm/dwm.c b/config/dwm/dwm.c deleted file mode 100644 index 7e44d659..00000000 --- a/config/dwm/dwm.c +++ /dev/null @@ -1,2049 +0,0 @@ -/* 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 -#ifdef XINERAMA -#include -#endif /* XINERAMA */ -#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 ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) -#define LENGTH(X) (sizeof X / sizeof X[0]) -#define MOUSEMASK (BUTTONMASK | PointerMotionMask) -#define WIDTH(X) ((X)->w + 2 * (X)->bw) -#define HEIGHT(X) ((X)->h + 2 * (X)->bw) -#define TAGMASK ((1 << LENGTH(tags)) - 1) -#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) - -/* enums */ -enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ -enum { SchemeNorm, SchemeSel }; /* color schemes */ -enum { - NetSupported, - NetWMName, - NetWMState, - NetWMCheck, - NetWMFullscreen, - NetActiveWindow, - NetWMWindowType, - NetWMWindowTypeDialog, - NetClientList, - NetLast -}; /* EWMH atoms */ -enum { - WMProtocols, - WMDelete, - WMState, - WMTakeFocus, - WMLast -}; /* default atoms */ -enum { - ClkTagBar, - ClkLtSymbol, - ClkStatusText, - ClkWinTitle, - ClkClientWin, - ClkRootWin, - ClkLast -}; /* clicks */ - -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; - 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, isfloating, isurgent, neverfocus, oldstate, isfullscreen; - 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; - -struct Monitor { - char ltsymbol[16]; - float mfact; - int nmaster; - int num; - int by; /* bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; - int showbar; - int topbar; - Client *clients; - Client *sel; - Client *stack; - Monitor *next; - Window barwin; - const Layout *lt[2]; -}; - -typedef struct { - const char *class; - const char *instance; - const char *title; - unsigned int tags; - int isfloating; - int monitor; -} Rule; - -/* 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 destroynotify(XEvent *e); -static void detach(Client *c); -static void detachstack(Client *c); -static Monitor *dirtomon(int dir); -static void drawbar(Monitor *m); -static void drawbars(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 Atom getatomprop(Client *c, Atom prop); -static int getrootptr(int *x, int *y); -static long getstate(Window w); -static int gettextprop(Window w, Atom atom, char *text, unsigned int size); -static void grabbuttons(Client *c, int focused); -static void grabkeys(void); -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 Client *nexttiled(Client *c); -static void pop(Client *c); -static void propertynotify(XEvent *e); -static void quit(const Arg *arg); -static Monitor *recttomon(int x, int y, int w, int h); -static void resize(Client *c, int x, int y, int w, int h, int interact); -static void resizeclient(Client *c, int x, int y, int w, int h); -static void resizemouse(const Arg *arg); -static void restack(Monitor *m); -static void run(void); -static void scan(void); -static int sendevent(Client *c, Atom proto); -static void sendmon(Client *c, Monitor *m); -static void setclientstate(Client *c, long state); -static void setfocus(Client *c); -static void setfullscreen(Client *c, int fullscreen); -static void setlayout(const Arg *arg); -static void setmfact(const Arg *arg); -static void setup(void); -static void seturgent(Client *c, int urg); -static void showhide(Client *c); -static void spawn(const Arg *arg); -static void tag(const Arg *arg); -static void tagmon(const Arg *arg); -static void tile(Monitor *m); -static void togglebar(const Arg *arg); -static void togglefloating(const Arg *arg); -static void toggletag(const Arg *arg); -static void toggleview(const Arg *arg); -static void unfocus(Client *c, int setfocus); -static void unmanage(Client *c, int destroyed); -static void unmapnotify(XEvent *e); -static void updatebarpos(Monitor *m); -static void updatebars(void); -static void updateclientlist(void); -static int updategeom(void); -static void updatenumlockmask(void); -static void updatesizehints(Client *c); -static void updatestatus(void); -static void updatetitle(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 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 const char broken[] = "broken"; -static char stext[256]; -static int screen; -static int sw, sh; /* X display screen geometry width, height */ -static int bh; /* bar height */ -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, - [UnmapNotify] = unmapnotify}; -static Atom wmatom[WMLast], netatom[NetLast]; -static int running = 1; -static Cur *cursor[CurLast]; -static Clr **scheme; -static Display *dpy; -static Drw *drw; -static Monitor *mons, *selmon; -static Window root, wmcheckwin; - -/* configuration, allows nested code to access above variables */ -#include "config.h" - -/* 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->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->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) { - 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) { - 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; - 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) { - 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; - } else if (ev->x < x + TEXTW(selmon->ltsymbol)) - click = ClkLtSymbol; - else if (ev->x > selmon->ww - (int)TEXTW(stext)) - click = ClkStatusText; - else - click = ClkWinTitle; - } else if ((c = wintoclient(ev->window))) { - focus(c); - restack(selmon); - XAllowEvents(dpy, ReplayPointer, CurrentTime); - click = ClkClientWin; - } - 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 && 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); - for (i = 0; i < CurLast; i++) - drw_cur_free(drw, cursor[i]); - for (i = 0; i < LENGTH(colors); i++) - free(scheme[i]); - free(scheme); - XDestroyWindow(dpy, wmcheckwin); - drw_free(drw); - XSync(dpy, False); - XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); - XDeleteProperty(dpy, root, netatom[NetActiveWindow]); -} - -void cleanupmon(Monitor *mon) { - Monitor *m; - - if (mon == mons) - mons = mons->next; - else { - for (m = mons; m && m->next != mon; m = m->next) - ; - m->next = mon->next; - } - XUnmapWindow(dpy, mon->barwin); - XDestroyWindow(dpy, mon->barwin); - free(mon); -} - -void clientmessage(XEvent *e) { - XClientMessageEvent *cme = &e->xclient; - Client *c = wintoclient(cme->window); - - 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); - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); - } - 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; - - m = ecalloc(1, sizeof(Monitor)); - m->tagset[0] = m->tagset[1] = 1; - m->mfact = mfact; - m->nmaster = nmaster; - m->showbar = showbar; - m->topbar = topbar; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); - return m; -} - -void destroynotify(XEvent *e) { - Client *c; - XDestroyWindowEvent *ev = &e->xdestroywindow; - - if ((c = wintoclient(ev->window))) - unmanage(c, 1); -} - -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; -} - -void drawbar(Monitor *m) { - int x, w, tw = 0; - int boxs = drw->fonts->h / 9; - int boxw = drw->fonts->h / 6 + 2; - unsigned int i, occ = 0, urg = 0; - Client *c; - - if (!m->showbar) - return; - - /* draw status first so it can be overdrawn by tags later */ - if (m == selmon) { /* status is only drawn on selected monitor */ - drw_setscheme(drw, scheme[SchemeNorm]); - tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ - drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0); - } - - for (c = m->clients; c; c = c->next) { - occ |= c->tags; - if (c->isurgent) - urg |= c->tags; - } - x = 0; - for (i = 0; i < LENGTH(tags); i++) { - w = TEXTW(tags[i]); - drw_setscheme( - drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); - if (occ & 1 << i) - drw_rect(drw, x + boxs, 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[SchemeNorm]); - x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); - - if ((w = m->ww - tw - x) > bh) { - if (m->sel) { - drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); - if (m->sel->isfloating) - drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); - } else { - drw_setscheme(drw, scheme[SchemeNorm]); - drw_rect(drw, x, 0, w, bh, 1, 1); - } - } - drw_map(drw, m->barwin, 0, 0, m->ww, bh); -} - -void drawbars(void) { - Monitor *m; - - for (m = mons; m; m = m->next) - drawbar(m); -} - -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); -} - -void focus(Client *c) { - if (!c || !ISVISIBLE(c)) - for (c = selmon->stack; c && !ISVISIBLE(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(); -} - -/* 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); c = c->next) - ; - if (!c) - for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next) - ; - } else { - for (i = selmon->clients; i != selmon->sel; i = i->next) - if (ISVISIBLE(i)) - c = i; - if (!c) - for (; i; i = i->next) - if (ISVISIBLE(i)) - c = i; - } - 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; - - if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, - &da, &di, &dl, &dl, &p) == Success && - p) { - atom = *(Atom *)p; - 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; -} - -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, k; - unsigned int modifiers[] = {0, LockMask, numlockmask, - numlockmask | LockMask}; - int start, end, skip; - KeySym *syms; - - XUngrabKey(dpy, AnyKey, AnyModifier, root); - XDisplayKeycodes(dpy, &start, &end); - syms = XGetKeyboardMapping(dpy, start, end - start + 1, &skip); - if (!syms) - return; - for (k = start; k <= end; k++) - for (i = 0; i < LENGTH(keys); i++) - /* skip modifier codes, we do that ourselves */ - if (keys[i].keysym == syms[(k - start) * skip]) - for (j = 0; j < LENGTH(modifiers); j++) - XGrabKey(dpy, k, keys[i].mod | modifiers[j], root, True, - GrabModeAsync, GrabModeAsync); - XFree(syms); - } -} - -void incnmaster(const Arg *arg) { - selmon->nmaster = 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, wmatom[WMDelete])) { - 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; - - 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 = 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); - 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 */ - setclientstate(c, NormalState); - if (c->mon == selmon) - unfocus(selmon->sel, 0); - c->mon->sel = c; - arrange(c->mon); - 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; - - 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); - for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) - resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); -} - -void motionnotify(XEvent *e) { - static Monitor *mon = NULL; - Monitor *m; - XMotionEvent *ev = &e->xmotion; - - 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 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)); c = c->next) - ; - return c; -} - -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 ((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(); - break; - } - if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { - updatetitle(c); - if (c == c->mon->sel) - drawbar(c->mon); - } - if (ev->atom == netatom[NetWMWindowType]) - updatewindowtype(c); - } -} - -void quit(const Arg *arg) { running = 0; } - -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 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 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; - 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 restack(Monitor *m) { - Client *c; - XEvent ev; - XWindowChanges wc; - - drawbar(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); - focus(NULL); - arrange(NULL); -} - -void setclientstate(Client *c, long state) { - long data[] = {state, None}; - - XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32, - PropModeReplace, (unsigned char *)data, 2); -} - -int sendevent(Client *c, Atom proto) { - int n; - Atom *protocols; - int exists = 0; - XEvent ev; - - if (XGetWMProtocols(dpy, c->win, &protocols, &n)) { - while (!exists && n--) - exists = protocols[n] == proto; - XFree(protocols); - } - if (exists) { - ev.type = ClientMessage; - ev.xclient.window = c->win; - ev.xclient.message_type = wmatom[WMProtocols]; - ev.xclient.format = 32; - ev.xclient.data.l[0] = proto; - ev.xclient.data.l[1] = CurrentTime; - XSendEvent(dpy, c->win, False, NoEventMask, &ev); - } - return exists; -} - -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, wmatom[WMTakeFocus]); -} - -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 ^= 1; - if (arg && arg->v) - selmon->lt[selmon->sellt] = (Layout *)arg->v; - strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, - sizeof selmon->ltsymbol); - if (selmon->sel) - arrange(selmon); - else - drawbar(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 = f; - arrange(selmon); -} - -void setup(void) { - int i; - XSetWindowAttributes wa; - Atom utf8string; - struct sigaction sa; - - /* do not transform children into zombies when they terminate */ - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT | SA_RESTART; - sa.sa_handler = SIG_IGN; - sigaction(SIGCHLD, &sa, NULL); - - /* clean up any zombies (inherited from .xinitrc etc) immediately */ - while (waitpid(-1, NULL, WNOHANG) > 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; - 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[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", 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); - /* 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); - /* init appearance */ - scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); - for (i = 0; i < LENGTH(colors); i++) - scheme[i] = drw_scm_create(drw, colors[i], 3); - /* init bars */ - updatebars(); - updatestatus(); - /* 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); - XDeleteProperty(dpy, root, netatom[NetClientList]); - /* 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 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 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 spawn(const Arg *arg) { - struct sigaction sa; - - // commented out because we dont use dmenu - /* if (arg->v == dmenucmd) */ - /* dmenumon[0] = '0' + selmon->num; */ - if (fork() == 0) { - if (dpy) - close(ConnectionNumber(dpy)); - setsid(); - - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = SIG_DFL; - sigaction(SIGCHLD, &sa, NULL); - - execvp(((char **)arg->v)[0], (char **)arg->v); - die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]); - } -} - -void tag(const Arg *arg) { - if (selmon->sel && arg->ui & TAGMASK) { - selmon->sel->tags = arg->ui & TAGMASK; - focus(NULL); - arrange(selmon); - } -} - -void tagmon(const Arg *arg) { - if (!selmon->sel || !mons->next) - return; - sendmon(selmon->sel, dirtomon(arg->i)); -} - -void tile(Monitor *m) { - unsigned int i, n, h, mw, my, ty; - Client *c; - - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) - ; - if (n == 0) - return; - - if (n > m->nmaster) - mw = m->nmaster ? m->ww * m->mfact : 0; - else - mw = m->ww; - for (i = my = ty = 0, c = nexttiled(m->clients); c; - c = nexttiled(c->next), i++) - if (i < m->nmaster) { - h = (m->wh - my) / (MIN(n, m->nmaster) - i); - resize(c, m->wx, m->wy + my, mw - (2 * c->bw), h - (2 * c->bw), 0); - if (my + HEIGHT(c) < m->wh) - my += HEIGHT(c); - } else { - h = (m->wh - ty) / (n - i); - resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2 * c->bw), - h - (2 * c->bw), 0); - if (ty + HEIGHT(c) < m->wh) - ty += HEIGHT(c); - } -} - -void togglebar(const Arg *arg) { - selmon->showbar = !selmon->showbar; - updatebarpos(selmon); - XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, - bh); - 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 toggletag(const Arg *arg) { - unsigned int newtags; - - if (!selmon->sel) - return; - newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); - if (newtags) { - selmon->sel->tags = newtags; - focus(NULL); - arrange(selmon); - } -} - -void toggleview(const Arg *arg) { - unsigned int newtagset = - selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); - - if (newtagset) { - selmon->tagset[selmon->seltags] = newtagset; - focus(NULL); - arrange(selmon); - } -} - -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); - 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); - } -} - -void updatebars(void) { - Monitor *m; - XSetWindowAttributes wa = {.override_redirect = True, - .background_pixmap = ParentRelative, - .event_mask = ButtonPressMask | ExposureMask}; - XClassHint ch = {"dwm", "dwm"}; - for (m = mons; m; m = m->next) { - if (m->barwin) - continue; - m->barwin = XCreateWindow( - dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), - CopyFromParent, DefaultVisual(dpy, screen), - CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); - XMapRaised(dpy, m->barwin); - XSetClassHint(dpy, m->barwin, &ch); - } -} - -void updatebarpos(Monitor *m) { - m->wy = m->my; - m->wh = m->mh; - if (m->showbar) { - m->wh -= bh; - m->by = m->topbar ? m->wy : m->wy + m->wh; - m->wy = m->topbar ? m->wy + bh : m->wy; - } else - m->by = -bh; -} - -void updateclientlist(void) { - 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); -} - -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); -} - -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->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) { - if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ - if (arg->ui & TAGMASK) - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; - focus(NULL); - arrange(selmon); -} - -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; -} - -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) - 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; -} - -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) - 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"); - 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/config/dwm/dwm.png b/config/dwm/dwm.png deleted file mode 100644 index b1f9ba7e..00000000 Binary files a/config/dwm/dwm.png and /dev/null differ diff --git a/config/dwm/transient.c b/config/dwm/transient.c deleted file mode 100644 index 040adb5b..00000000 --- a/config/dwm/transient.c +++ /dev/null @@ -1,42 +0,0 @@ -/* 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/config/dwm/util.c b/config/dwm/util.c deleted file mode 100644 index 96b82c98..00000000 --- a/config/dwm/util.c +++ /dev/null @@ -1,36 +0,0 @@ -/* 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/config/dwm/util.h b/config/dwm/util.h deleted file mode 100644 index f633b517..00000000 --- a/config/dwm/util.h +++ /dev/null @@ -1,8 +0,0 @@ -/* 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/config/dwmbar/bar.sh b/config/dwmbar/bar.sh deleted file mode 100755 index 8522b8fc..00000000 --- a/config/dwmbar/bar.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh - -blue=#0000ff - -battery() { - get_capacity="$(cat /sys/class/power_supply/BAT1/capacity)" - get_status="$(cat /sys/class/power_supply/BAT1/status)" - case "$get_status" in - Charging) printf "󰂄 $get_capacity" ;; - Discharging) printf "󰁹 $get_capacity" ;; - esac -} - -audio() { - get_vol=$(pamixer --get-volume-human) - if [ $get_vol = 'muted' ]; then - printf "󰕾 Muted" - else - printf "󰕾 $get_vol" - fi -} - -clock() { - printf "$(date '+%H:%M') " -} - -while true; do - xsetroot -name " $(clock) $(audio) $(battery) " - sleep 1 -done diff --git a/config/emacs/.mbsyncrc b/config/emacs/.mbsyncrc index adbabf4c..a8e5f73a 100644 --- a/config/emacs/.mbsyncrc +++ b/config/emacs/.mbsyncrc @@ -1,9 +1,10 @@ IMAPAccount outlook +AuthMechs XOAUTH2 Host outlook.office365.com Port 993 -UserCmd "pass Microsoft | awk 'BEGIN {ORS=\"\"} FNR == 2{gsub(\"login: \", \"\"); gsub(/ /, \"\"); print}'" -PassCmd "pass Microsoft" -SSLType IMAPS +UserCmd "pass Microsoft | grep 'login:' | sed 's/login: //'" +PassCmd "oama access $(pass Microsoft | grep 'login:' | sed 's/login: //')" +TLSType IMAPS IMAPStore outlook-remote Account outlook @@ -21,20 +22,68 @@ Create Both Expunge Both SyncState * +IMAPAccount gmail-1 +AuthMechs XOAUTH2 +Host imap.gmail.com +Port 993 +UserCmd "pass accounts.google.com/one | grep 'login:' | sed 's/login: //'" +PassCmd "oama access $(pass accounts.google.com/one | grep 'login:' | sed 's/login: //')" +TLSType IMAPS + +IMAPStore gmail-1-remote +Account gmail-1 + +MaildirStore gmail-1-local +Subfolders Verbatim +Path ~/Mail/gmail-one/ +Inbox ~/Mail/gmail-one/Inbox + +Channel gmail-1 +Far :gmail-1-remote: +Near :gmail-1-local: +Patterns * !"[Gmail]/All Mail" !"[Gmail]/Important" !"[Gmail]/Starred" !"[Gmail]/Bin" +Create Both +Expunge Both +SyncState * + +IMAPAccount gmail-2 +AuthMechs XOAUTH2 +Host imap.gmail.com +Port 993 +UserCmd "pass accounts.google.com/two| grep 'login:' | sed 's/login: //'" +PassCmd "oama access $(pass accounts.google.com/two | grep 'login:' | sed 's/login: //')" +TLSType IMAPS + +IMAPStore gmail-2-remote +Account gmail-2 + +MaildirStore gmail-2-local +Subfolders Verbatim +Path ~/Mail/gmail-two/ +Inbox ~/Mail/gmail-two/Inbox + +Channel gmail-2 +Far :gmail-2-remote: +Near :gmail-2-local: +Patterns * !"[Gmail]/All Mail" !"[Gmail]/Important" !"[Gmail]/Starred" !"[Gmail]/Bin" +Create Both +Expunge Both +SyncState * + IMAPAccount proton Host 127.0.0.1 Port 1143 -UserCmd "pass 'Proton Account' | awk 'BEGIN {ORS=\"\"} FNR == 2{gsub(\"login: \", \"\"); gsub(/ /, \"\"); print}'" +UserCmd "pass 'Proton Account' | grep 'login:' | sed 's/login: //'" PassCmd "cat ~/.hydroxide-bridge-pass" -SSLType none +TLSType None IMAPStore proton-remote Account proton MailDirStore proton-local SubFolders Verbatim -Path ~/Mail/Proton/ -Inbox ~/Mail/Proton/Inbox +Path ~/.mail/proton/ +Inbox ~/.mail/proton/Inbox Channel proton Far :proton-remote: @@ -43,3 +92,25 @@ Patterns * Create Both Expunge Both SyncState * + +IMAPAccount li +AuthMechs * +UserCmd "pass show email/li | grep 'login: ' | sed 's/login: //'" +PassCmd "pass show email/li" +Tunnel "nc -T protocols=all -T ciphers=compat -X 5 -x " + +IMAPStore li-remote +Account li + +MailDirStore li-local +SubFolders Verbatim +Path ~/.mail/li/ +Inbox ~/.mail/li/Inbox + +Channel li +Far :li-remote: +Near :li-local: +Patterns * +Create Both +Expunge Both +SyncState * diff --git a/config/emacs/.offlineimap.py b/config/emacs/.offlineimap.py new file mode 100644 index 00000000..fed1df0b --- /dev/null +++ b/config/emacs/.offlineimap.py @@ -0,0 +1,52 @@ +#! /usr/bin/env python +from subprocess import check_output +import re + + +def get_pass(account): + return check_output("pass " + account, shell=True).splitlines()[0] + + +def get_user(account): + usercmd = check_output("pass " + account, shell=True) + + return re.search(rb"login: (.*)", usercmd, flags=0).group(1).decode("utf-8") + + +def get_host(account): + usercmd = check_output("pass " + account, shell=True) + + return re.search(rb"host: (.*)", usercmd, flags=0).group(1).decode("utf-8") + + +def hydroxide(path): + + file = open(path, "r") + + pword = file.read() + + return pword + + +def get_client_id(account): + cmd = check_output("pass " + account, shell=True) + + output = re.search("client_id: (.*)", cmd.decode(), flags=0).group(1) + + return output + + +def get_client_secret(account): + cmd = check_output("pass " + account, shell=True) + + output = re.search("client_secret: (.*)", cmd.decode(), flags=0).group(1) + + return output + + +def get_client_refresh_token(account): + cmd = check_output("pass " + account, shell=True) + + output = re.search("client_refresh_token: (.*)", cmd.decode(), flags=0).group(1) + + return output diff --git a/config/emacs/.offlineimaprc b/config/emacs/.offlineimaprc new file mode 100644 index 00000000..b02de929 --- /dev/null +++ b/config/emacs/.offlineimaprc @@ -0,0 +1,112 @@ +[general] +pythonfile = ~/.offlineimap.py +accounts = Proton, Outlook, Gmail-personal-1, Gmail-personal-2, li +socktimeout = 60 + +[Account Proton] +localrepository = Proton-local +remoterepository = Proton-remote + +[Repository Proton-local] +type = Maildir +localfolders = ~/.mail/protonmail + +[Repository Proton-remote] +type = IMAP +ssl = no +remotehost = 127.0.0.1 +remoteport = 1143 +remoteusereval = get_user("Proton\ Account") +remotepasseval = hydroxide("/home/sako/.hydroxide-bridge-pass") +folderfilter = lambda foldername: foldername in [ "All Mail", "Archive", "Drafts", "INBOX", "Sent", "Spam", "Starred", "Trash" ] + +[Account Outlook] +localrepository = Outlook-local +remoterepository = Outlook-remote + +[Repository Outlook-local] +type = Maildir +localfolders = ~/.mail/outlook + +[Repository Outlook-remote] +ssl = yes +sslcacertfile = /etc/ssl/certs/ca-certificates.crt +type = IMAP +remoteusereval = get_user("Microsoft") +remotehost = outlook.office365.com +remoteport = 993 +auth_mechanisms = XOAUTH2 +oauth2_request_url = https://login.microsoftonline.com/common/oauth2/v2.0/token +# Thunderbird client_id below +oauth2_client_id = 9e5f94bc-e8a4-4e73-b8be-63364c29d753 +# Do not need client_secret :D +oauth2_client_secret = +oauth2_refresh_token_eval = get_client_refresh_token("Microsoft") +folderfilter = lambda folder: not folder.startswith('Calendar') and not folder.startswith('Contacts') + +[Account Gmail-personal-1] +localrepository = Gmail-personal-1-local +remoterepository = Gmail-personal-1-remote + +[Repository Gmail-personal-1-local] +type = GmailMaildir +localfolders = ~/.mail/gmail1 +# Google IMAP weirdness +nametrans = lambda f: '[Gmail]/' + f if f in ['Drafts', 'Starred', 'Important', 'Spam', 'Trash', 'All Mail', 'Sent Mail'] else f + +[Repository Gmail-personal-1-remote] +ssl = yes +sslcacertfile = /etc/ssl/certs/ca-certificates.crt +type = Gmail +remotehost = imap.gmail.com +auth_mechanisms = XOAUTH2 +remoteusereval = get_user("accounts.google.com/one") +oauth2_request_url = https://accounts.google.com/o/oauth2/token +oauth2_client_id_eval = get_client_id("email/oauth/gmail") +oauth2_client_secret_eval = get_client_secret("email/oauth/gmail") +oauth2_refresh_token_eval = get_client_refresh_token("accounts.google.com/one") +# Google IMAP weirdness +nametrans = lambda f: f.replace('[Gmail]/', '') if f.startswith('[Gmail]/') else f + +[Account Gmail-personal-2] +localrepository = Gmail-personal-2-local +remoterepository = Gmail-personal-2-remote + +[Repository Gmail-personal-2-local] +type = GmailMaildir +localfolders = ~/.mail/gmail2 +# Google IMAP weirdness +nametrans = lambda f: '[Gmail]/' + f if f in ['Drafts', 'Starred', 'Important', 'Spam', 'Trash', 'All Mail', 'Sent Mail'] else f + +[Repository Gmail-personal-2-remote] +ssl = yes +sslcacertfile = /etc/ssl/certs/ca-certificates.crt +type = Gmail +remotehost = imap.gmail.com +auth_mechanisms = XOAUTH2 +remoteusereval = get_user("accounts.google.com/two") +oauth2_request_url = https://accounts.google.com/o/oauth2/token +oauth2_client_id_eval = get_client_id("email/oauth/gmail") +oauth2_client_secret_eval = get_client_secret("email/oauth/gmail") +oauth2_refresh_token_eval = get_client_refresh_token("accounts.google.com/two") +# Google IMAP weirdness +nametrans = lambda f: f.replace('[Gmail]/', '') if f.startswith('[Gmail]/') else f + +[Account li] +localrepository = li-local +remoterepository = li-remote +proxy = SOCKS5:localhost:9050 + +[Repository li-local] +type = Maildir +localfolders = ~/.mail/li + +[Repository li-remote] +type = IMAP +ssl = yes +sslcacertfile = /etc/ssl/certs/ca-certificates.crt +remotehosteval = get_host("email/li") +remoteport = 993 +remoteusereval = get_user("email/li") +remotepasseval = get_pass("email/li") + diff --git a/config/emacs/emacs.org b/config/emacs/emacs.org index bef286dc..330ea2bb 100644 --- a/config/emacs/emacs.org +++ b/config/emacs/emacs.org @@ -1,1469 +1,1585 @@ -#+title: EMACS 2 -#+PROPERTY: header-args:emacs-lisp :tangle yes :tangle init.el -* Welcome! -#+begin_src emacs-lisp -;; -*- lexical-binding: t; -*- -#+end_src -* Package Setup -#+begin_src emacs-lisp - (message "Reached package setup") - - (require `package) - - (setq package-archives `(("mepla" . "https://melpa.org/packages/") - ("org" . "https://orgmode.org/elpa/") - ("elpa" . "https://elpa.gnu.org/packages/"))) - - (package-initialize) - - (unless (package-installed-p 'use-package) - (progn - (package-refresh-contents) - (package-install 'use-package))) - - (require 'use-package) - (setq use-package-always-ensure t) - - ;; TODO add better detection to this - (when (eq system-type 'windows-nt) - (message "setting up straight.el") - (defvar bootstrap-version) - (let ((bootstrap-file - (expand-file-name - "straight/repos/straight.el/bootstrap.el" - (or (bound-and-true-p straight-base-dir) - user-emacs-directory))) - (bootstrap-version 7)) - (unless (file-exists-p bootstrap-file) - (with-current-buffer - (url-retrieve-synchronously - "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el" - 'silent 'inhibit-cookies) - (goto-char (point-max)) - (eval-print-last-sexp))) - (load bootstrap-file nil 'nomessage)) - (setq straight-use-package-by-default t)) -#+end_src -* Make Emacs faster -#+begin_src emacs-lisp -(message "Speeding up") -#+end_src -** Avoid garbage collection at startup -#+begin_src emacs-lisp -(use-package gcmh - :init - (setq gcmh-idle-delay 5) - (setq gcmh-high-cons-threshold (* 16 1024 1024)) - :config - (gcmh-mode)) -#+end_src -** Set garbage collection to be further back -#+begin_src emacs-lisp -(setq gc-cons-threshold most-positive-fixnum) -#+end_src -** Unset file-name-handler-alist -#+begin_src emacs-lisp -(defvar sakomacs--file-name-handler-alist file-name-handler-alist) -(setq file-name-handler-alist nil) - -;; Alternatively, restore it even later: -(add-hook 'emacs-startup-hook - (lambda () - (setq file-name-handler-alist sakomacs--file-name-handler-alist))) -#+end_src -** Reset gc once init has finished -#+begin_src emacs-lisp - (defun doom-defer-garbage-collection-h () - "Disable garbage collection." - (setq gc-cons-threshold most-positive-fixnum)) - -(defun doom-restore-garbage-collection-h () - "Restore garbage collection." - (run-at-time - 1 nil (lambda () (setq gc-cons-threshold 16777216)))) - -(add-hook 'minibuffer-setup-hook #'doom-defer-garbage-collection-h) -(add-hook 'minibuffer-exit-hook #'doom-restore-garbage-collection-h) -#+end_src -** Read more -#+begin_src emacs-lisp -(setq read-process-output-max (* 1024 1024)) ;; 1mb -#+end_src -* Keybinds -Ill use this later eventually -#+begin_src emacs-lisp -(message "Got to keybinds") -#+end_src -** Make emacs more human -#+begin_src emacs-lisp -(global-set-key (kbd "") 'keyboard-escape-quit) -#+end_src -* Core -#+begin_src elisp - (message "Reached core.") -#+end_src -** Encoding -#+begin_src emacs-lisp -(setq utf-translate-cjk-mode nil) ; disable CJK coding/encoding (Chinese/Japanese/Korean characters) -(set-language-environment 'utf-8) -(set-keyboard-coding-system 'utf-8) ; For old Carbon emacs on OS X only -(setq locale-coding-system 'utf-8) -(set-default-coding-systems 'utf-8) -(set-terminal-coding-system 'utf-8) -(set-selection-coding-system - (if (eq system-type 'windows-nt) - 'utf-16-le ;; https://rufflewind.com/2014-07-20/pasting-unicode-in-emacs-on-windows - 'utf-8)) -(prefer-coding-system 'utf-8) -#+end_src -** Cleanup .emacs.d -#+begin_src emacs-lisp -(setq backup-directory-alist '(("." . "~/.emacs.d/backup")) -backup-by-copying t -version-control t -delete-old-versions t -kept-new-versions 20 -kept-old-versions 5) - -(use-package no-littering - :config - (setq custom-file (if (boundp 'server-socket-dir) - (expand-file-name "custom.el" server-socket-dir) - (no-littering-expand-etc-file-name "custom.el"))) - (when (file-exists-p custom-file) - (load custom-file t)) - - ;; Don't litter project folders with backup files - (let ((backup-dir (no-littering-expand-var-file-name "backup/"))) - (make-directory backup-dir t) - (setq backup-directory-alist - `(("\\`/tmp/" . nil) - ("\\`/dev/shm/" . nil) - ("." . ,backup-dir)))) - - (setq auto-save-default nil) - - ;; Tidy up auto-save files - (setq auto-save-default nil) - (let ((auto-save-dir (no-littering-expand-var-file-name "auto-save/"))) - (make-directory auto-save-dir t) - (setq auto-save-file-name-transforms - `(("\\`/[^/]*:\\([^/]*/\\)*\\([^/]*\\)\\'" - ,(concat temporary-file-directory "\\2") t) - ("\\`\\(/tmp\\|/dev/shm\\)\\([^/]*/\\)*\\(.*\\)\\'" "\\3") - ("." ,auto-save-dir t))))) - -;; no-littering doesn't set this by default so we must place -;; auto save files in the same path as it uses for sessions -(setq auto-save-file-name-transforms - `((".*" ,(no-littering-expand-var-file-name "auto-save/") t))) -#+end_src -** Native Compilation -#+begin_src emacs-lisp -(setq native-comp-async-report-warnings-errors nil) - -(add-to-list 'native-comp-eln-load-path (expand-file-name "eln-cache/" user-emacs-directory)) -#+end_src -** Emacs settings -#+begin_src emacs-lisp -(setq inhibit-startup-message t) - -;; make emacs look a little more cleaner -(scroll-bar-mode -1) -(tool-bar-mode -1) -(tooltip-mode -1) -(set-fringe-mode 10) -(menu-bar-mode -1) - -;; this is really annoying i hate it -(setq visible-bell nil) - -;; -- core keybinds and packages -- -(repeat-mode 1) - -(column-number-mode) - -(dolist (mode '(text-mode-hook - prog-mode-hook - conf-mode-hook)) - (add-hook mode (lambda () (display-line-numbers-mode 1)))) -#+end_src -** Core Keybinds -#+begin_src emacs-lisp -(repeat-mode 1) - -(column-number-mode) - -(dolist (mode '(text-mode-hook - prog-mode-hook - conf-mode-hook)) - (add-hook mode (lambda () (display-line-numbers-mode 1)))) -#+end_src -** Appearance -#+begin_src emacs-lisp - (use-package doom-themes - :config - (load-theme 'doom-sourcerer t)) - - ;; emacsclient things - (setq frame-resize-pixelwise t) - ;; ui settings apparently go below - (setq default-frame-alist '((font . "JetBrainsMono NF") - '(vertical-scroll-bars . nil) - '(horizontal-scroll-bars . nil))) - - ;; GO AWAY - (defun my/disable-scroll-bars (frame) - (modify-frame-parameters frame - '((vertical-scroll-bars . nil) - (horizontal-scroll-bars . nil)))) - (add-hook 'after-make-frame-functions 'my/disable-scroll-bars) - - - ;; y/n is better than yes/no - (fset 'yes-or-no-p 'y-or-n-p) - - ;; font - (set-face-attribute 'default nil - :font "JetBrainsMono NF" - :weight 'light - :height 125) -#+end_src -** Emacs Client -#+begin_src emacs-lisp -(setq frame-resize-pixelwise t) -;; ui settings apparently go below -(setq default-frame-alist '((font . "JetBrainsMono NF") - '(vertical-scroll-bars . nil) - '(horizontal-scroll-bars . nil))) -#+end_src -** Modeline -#+begin_src emacs-lisp - (use-package nerd-icons - :custom - (nerd-icons-font-family "JetBrainsMono NF")) - (use-package doom-modeline - :custom - (doom-modeline-height 35) - (doom-modeline-modal-modern-icon nil) - :init (doom-modeline-mode 1)) -#+end_src -** Editor Configuration -#+begin_src emacs-lisp -(use-package super-save - :config - (super-save-mode +1) - (setq super-save-auto-save-when-idle t)) - -;; revert dired and other buffers -(setq global-auto-revert-non-file-buffers t) - -;; revert buffers when file has been changed -(global-auto-revert-mode 1) - -;; popups and stuff -(use-package popper - :bind (("C-M-'" . popper-toggle) - ("M-'" . popper-cycle) - ("C-M-\"" . popper-toggle-type)) - :custom - (popper-window-height 12) - (popper-reference-buffers '(eshell-mode - vterm-mode - geiser-repl-mode - help-mode - grep-mode - helpful-mode - compilation-mode)) - :config - (popper-mode 1)) -#+end_src -** Helpful -#+begin_src emacs-lisp -(use-package helpful - :custom - (counsel-describe-function-function #'helpful-callable) - (counsel-describe-variable-function #'helpful-variable) - :bind (([remap describe-function] . helpful-function) - ([remap describe-symbol] . helpful-symbol) - ([remap describe-variable] . helpful-variable) - ([remap describe-command] . helpful-command) - ([remap describe-key] . helpful-key))) -#+end_src -** Which Key -#+begin_src emacs-lisp -;; incase i get lost -(use-package which-key - :init (which-key-mode) - :diminish which-key-mode - :config - (setq which-key-idle-delay 1)) -#+end_src -** Alerts -#+begin_src emacs-lisp -(when (eq system-type 'windows-nt) - (use-package alert - :commands (alert) - :config (setq alert-default-style 'toast)) - - (use-package alert-toast - :after alert)) -#+end_src -** Daemon -#+begin_src emacs-lisp -(if (eq system-type 'windows-nt) - (setq server-socket-dir "~/.emacs.d/server")) -(server-start) -#+end_src -* Keys -#+begin_src emacs-lisp -(message "got to keys setup") -#+end_src -** General -#+begin_src emacs-lisp - (use-package general - :config - (general-create-definer sk/leader-keys - :keymaps '(normal insert visual emacs) - :prefix "SPC" - :global-prefix "C-SPC") - - (sk/leader-keys - ;; code - "c" '(:ignore c :which-key "code") - "cc" '(compile :which-key "compile") - "cC" '(recompile :which-key "compile") - "cX" '(lsp-treeemacs-errors-list :which-ley "list errors") - ;; toggles - "t" '(:ignore t :which-key "toggles") - "tt" '(counsel-load-theme :which-key "choose theme") - "ts" '(hydra-text-scale/body :which-key "scale text") - ;; search - "s" '(:ignore s :which-key "search") - "sb" '(swiper :which-key "search buffer") - ;; insert - "i" '(:ignore i :which-key "insert") - "ie" '(emoji-search :which-key "Emoji") - ;; project - "p" '(:ignore p :which-key "projects") - "pp" '(project-switch-project :which-key "open project") - "pk" '(project-kill-buffers :which-key "close project") - "pt" '(magit-todos-list :which-key "list project todos") - "po" '(project-find-file :which-key "find file") - "pc" '(project-compile :which-key "compile project") - ;; open - "o" '(:ignore o :which-key "open") - "op" '(treemacs :which-key "treemacs") - "oP" '(treemacs-find-file :which-key "treemacs find file") - "oe" '(eshell :which-key "eshell") - "ov" '(vterm :which-key "vterm") - "or" '(elfeed :which-key "rss") - ;; notes - "n" '(:ignore o :which-key "notes") - "na" '(org-agenda :which-key "agenda") - "nf" '(org-roam-node-find :which-key "find node") - "nc" '(org-capture :which-key "capture") - "np" '(org-pomodoro :which-key "pomodoro") - "ne" '(:ignore ne :which-key "export") - "nep" '(org-latex-export-to-pdf :which-key "pdf") - ;; quit - "q" '(:ignore q :which-key "quit") - "qq" '(delete-frame :which-key "close emacs") - "qK" '(kill-emacs :which-key "quit emacs") - ;; git - "g" '(:ignore g :which-key "git") - "gs" '(magit-status :which-key "status") - "gc" '(:ignore gc :which-key "create") - "gcr" '(magit-init :which-key "init repo") - "gcR" '(magit-clone :which-key "clone repo") - "gcc" '(magit-commit-create :which-key "commit") - "gci" '(forge-create-issue :which-key "issue") - "gcp" '(forge-create-pullreq :which-key "pull request") - ;; mail - "m" '(mu4e :which-key "mu4e"))) - -#+end_src -** Evil -#+begin_src emacs-lisp - - (use-package evil - :init - ;; Pre-load configuration - (setq evil-want-integration t) - (setq evil-want-keybinding nil) - (setq evil-want-C-u-scroll t) - (setq evil-want-C-i-jump nil) - (setq evil-respect-visual-line-mode t) - (setq evil-undo-system 'undo-tree) - :config - (evil-mode 1) - - ;; use emacs state for these mods - (dolist (mode '(custom-mode - eshell-mode - git-rebase-mode - erc-mode - circe-server-mode - circe-chat-mode - circe-query-mode - term-mode)) - (add-to-list 'evil-emacs-state-modes mode)) - - (defun sk/dont-arrow-me-bro () - (interactive) - (message "STOP USING THE ARROW KEYS!!!!!!!!!!!!!!!!!!!!!!!")) - - ;; Disable arrow keys in normal and visual modes - (define-key evil-normal-state-map (kbd "") 'sk/dont-arrow-me-bro) - (define-key evil-normal-state-map (kbd "") 'sk/dont-arrow-me-bro) - (define-key evil-normal-state-map (kbd "") 'sk/dont-arrow-me-bro) - (define-key evil-normal-state-map (kbd "") 'sk/dont-arrow-me-bro) - (evil-global-set-key 'motion (kbd "") 'sk/dont-arrow-me-bro) - (evil-global-set-key 'motion (kbd "") 'sk/dont-arrow-me-bro) - (evil-global-set-key 'motion (kbd "") 'sk/dont-arrow-me-bro) - (evil-global-set-key 'motion (kbd "") 'sk/dont-arrow-me-bro) - - (evil-set-initial-state 'messages-buffer-mode 'normal) - (evil-set-initial-state 'dashboard-mode 'normal)) - - (use-package evil-collection - :after evil - :custom - (evil-collection-outline-bind-tab-p nil) - :config - ;; Is this a bug in evil-collection? - (setq evil-collection-company-use-tng nil) - (delete 'lispy evil-collection-mode-list) - (delete 'org-present evil-collection-mode-list) - ;; (delete 'mu4e evil-collection-mode-list) - ;; (delete 'mu4e-conversation evil-collection-mode-list) - (evil-collection-init)) - - (use-package evil-org - :after (evil org) - :hook ((org-mode . evil-org-mode) - (org-agenda-mode . evil-org-mode)) - :config - (require 'evil-org-agenda) - (evil-org-set-key-theme '(navigation todo insert textobjects additional)) - (evil-org-agenda-set-keys)) - - (use-package evil-nerd-commenter - :bind ("M-/" . evilnc-comment-or-uncomment-lines)) - - (with-eval-after-load 'org - (evil-define-key '(normal insert visual) org-mode-map (kbd "C-j") 'org-next-visible-heading) - (evil-define-key '(normal insert visual) org-mode-map (kbd "C-k") 'org-previous-visible-heading) - (evil-define-key '(normal insert visual) org-mode-map (kbd "M-j") 'org-metadown) - (evil-define-key '(normal insert visual) org-mode-map (kbd "M-k") 'org-metaup)) -#+end_src -* Interface -#+begin_src emacs-lisp -(message "Got to interface") -#+end_src -** Hydra -#+begin_src emacs-lisp -(use-package hydra) -#+end_src -** Vertico -#+begin_src emacs-lisp - (use-package vertico - :bind (:map vertico-map - ("C-j" . vertico-next) - ("C-k" . vertico-previous) - ("C-f" . vertico-exit-input) - :map minibuffer-local-map - ("M-h" . vertico-directory-up)) - :custom - (vertico-cycle t) - - :hook (rfn-eshadow-update-overlay . vertico-directory-tidy) - :init - (require 'vertico-directory) - (vertico-mode)) -#+end_src -** Marginalia -#+begin_src emacs-lisp -(use-package marginalia - :after vertico - :ensure t - :custom - (marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil)) - :init - (marginalia-mode)) -#+end_src -** Consult -#+begin_src emacs-lisp -(use-package consult - :bind (("C-s" . consult-line) - ("C-M-l" . consult-imenu) - ("C-M-j" . consult-buffer) - ("C-x C-b" . consult-buffer) - :map minibuffer-local-map - ("C-r" . consult-history))) - - -(use-package consult-dir - :bind (("C-x C-d" . consult-dir) - :map vertico-map - ("C-x C-d" . consult-dir) - ("C-x C-j" . consult-dir-jump-file)) - - :custom - (consult-dir-project-list-function nil)) -#+end_src -** Orderless -#+begin_src emacs-lisp -(use-package orderless - :config - (orderless-define-completion-style orderless+initialism - (orderless-matching-styles '(orderless-initialism - orderless-literal - orderless-regexp))) - - (setq completion-styles '(orderless) - completion-category-defaults nil - orderless-matching-styles '(orderless-literal orderless-regexp) - completion-category-overrides - '((file (styles partial-completion))))) -#+end_src -** Embark -#+begin_src emacs-lisp - (use-package embark - :after vertico - :bind (("C-." . embark-act) - ("M-." . embark-dwim) - :map minibuffer-local-map - ("C-d" . embark-act) - :map embark-region-map - ("D" . denote-region)) - - :config - ;; Remove the mixed indicator to prevent the popup from being displayed - ;; automatically - (delete #'embark-mixed-indicator embark-indicators) - (add-to-list 'embark-indicators 'embark-minimal-indicator) - - ;; Use Embark to show command prefix help - (setq prefix-help-command #'embark-prefix-help-command)) - - (use-package embark-consult - :after embark) - -#+end_src -** Corfu -#+begin_src emacs-lisp - (use-package corfu - :bind (:map corfu-map - ("C-j" . corfu-next) - ("C-k" . corfu-previous) - ("TAB" . corfu-insert) - ([tab] . corfu-insert) - ("C-f" . corfu-insert)) - :custom - (corfu-cycle t) - (corfu-auto t) - (corfu-preview-current nil) - (corfu-quit-at-boundary t) - (corfu-quit-no-match t) - (corfu-min-chars 3) - (corfu-auto-delay 0) - (corfu-auto-prefix 0) - :init - (global-corfu-mode) - - (defun corfu-enable-in-minibuffer () - "Enable Corfu in the minibuffer if `completion-at-point' is bound." - (when (where-is-internal #'completion-at-point (list (current-local-map))) - (setq-local corfu-auto nil) ;; Enable/disable auto completion - (setq-local corfu-echo-delay nil ;; Disable automatic echo and popup - corfu-popupinfo-delay nil) - (corfu-mode 1))) - - (add-hook 'minibuffer-setup-hook #'corfu-enable-in-minibuffer)) -#+end_src -** Dashboard -#+begin_src emacs-lisp - (use-package dashboard - :init - (setq initial-buffer-choice 'dashboard-open) - ;; Set the title - (setq dashboard-banner-logo-title "GET ME OUT GET ME OUT GET ME OUT") - (setq dashboard-image-banner-max-height 200) - ;; Set the banner - (setq dashboard-startup-banner '"~/.emacs.d/icon.png") - (setq dashboard-center-content t) - (setq dashboard-vertically-center-content t) - (setq dashboard-show-shortcuts nil) - - ;; nerd icons - (setq dashboard-display-icons-p t) ; display icons on both GUI and terminal - (setq dashboard-icon-type 'nerd-icons) ; use `nerd-icons' package - - ;; list stuff - (setq dashboard-items '((recents . 3) - (projects . 3) - (agenda . 3))) - :config - (dashboard-setup-startup-hook)) -#+end_src -* Auth -#+begin_src emacs-lisp -(message "Reached auth") -#+end_src -** Pinentry -#+begin_src emacs-lisp - (unless (eq system-type 'windows-nt) - (use-package pinentry - :config - (setq epa-pinentry-mode 'loopback)) - (pinentry-start)) -#+end_src -** Password-Store -#+begin_src emacs-lisp - (use-package password-store - :bind (("C-c p p" . password-store-copy) - ("C-c p i" . password-store-insert) - ("C-c p g" . password-store-generate)) - :config - (setq password-store-password-length 12)) - - (use-package auth-source-pass - :config - (auth-source-pass-enable)) -#+end_src -** OAuth2 -this should be useful later -#+begin_src emacs-lisp -(use-package oauth2 - :ensure t) -#+end_src -* Shell -#+begin_src emacs-lisp -(message "Reached shell") -#+end_src -** EShell -#+begin_src emacs-lisp -(defun sk/configure-eshell () - ;; Save command history when commands are entered - (add-hook 'eshell-pre-command-hook 'eshell-save-some-history) - - ;; Truncate buffer for performance - (add-to-list 'eshell-output-filter-functions 'eshell-truncate-buffer) - - ;; Bind some useful keys for evil-mode - (evil-define-key '(normal insert visual) eshell-mode-map (kbd "C-r") 'counsel-esh-history) - (evil-define-key '(normal insert visual) eshell-mode-map (kbd "") 'eshell-bol) - (evil-normalize-keymaps) - - (setq eshell-history-size 10000 - eshell-buffer-maximum-lines 10000 - eshell-hist-ignoredups t - eshell-scroll-to-bottom-on-input t)) - -(use-package eshell-git-prompt) - - - (add-hook 'eshell-first-time-mode 'sakomacs/configure-eshell) - - (with-eval-after-load 'esh-opt - (setq eshell-destroy-buffer-when-process-dies t) - (setq eshell-visual-commands '("htop" "zsh" "vim")) - - (eshell-git-prompt-use-theme 'powerline)) -#+end_src -** VTerm -#+begin_src emacs-lisp - (use-package vterm - :commands vterm - :config - (setq vterm-max-scrollback 10000)) -#+end_src -* Dev -#+begin_src emacs-lisp -(message "Reached dev") -#+end_src -** {} and () matching -#+begin_src emacs-lisp -(use-package smartparens - :hook (prog-mode . smartparens-mode) - :config - (sp-use-smartparens-bindings)) - -(use-package rainbow-delimiters - :hook (prog-mode . rainbow-delimiters-mode)) -#+end_src -** Compilation -#+begin_src emacs-lisp -(setq compilation-scroll-output t) - -(setq compilation-environment '("TERM=xterm-256color")) - -(defun sk/advice-compilation-filter (f proc string) - (funcall f proc (xterm-color-filter string))) - -(advice-add 'compilation-filter :around #'sk/advice-compilation-filter) - -(defun sk/auto-recompile-buffer () - (interactive) - (if (member #'recompile after-save-hook) - (remove-hook 'after-save-hook #'recompile t) - (add-hook 'after-save-hook #'recompile nil t))) -#+end_src -** Project.el -#+begin_src emacs-lisp -(setq project-switch-commands '((project-find-file "Find file" "f") (project-find-dir "Find dir" "d") (project-dired "Dired" "D") (consult-ripgrep "ripgrep" "g") (magit-project-status "Magit" "m"))) -#+end_src -** Eglot (LSP) -#+begin_src emacs-lisp - (use-package eglot - :bind (:map eglot-mode-map - ("C-c C-a" . eglot-code-actions) - ("C-c C-r" . eglot-rename)) - :config - (setq eglot-autoshutdown t - eglot-confirm-server-initiated-edits nil)) - - ;; this'll make it so i don't have to use vscode every now and then - ;; (when (eq system-type 'windows-nt) - ;; (use-package eglot-booster - ;; :straight (eglot-booster :type git :host github :repo "jdtsmith/eglot-booster") - ;; :after eglot - ;; :config (eglot-booster-mode)) - ;; ) - - (when (eq system-type 'gnu/linux) - (use-package eglot-booster - :ensure nil - :config (eglot-booster-mode))) -#+end_src -** Magit -#+begin_src emacs-lisp -(use-package magit - :bind ("C-M-;" . magit-status-here) - :custom - (magit-show-long-lines-warning nil) - (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)) - -(use-package magit-todos - :after magit - :config - (magit-todos-mode)) - -;; -- magit forge -- -(use-package forge - :after magit) -(setq auth-sources '("~/.authinfo")) - -(defhydra sk/smerge-panel () - "smerge" - ("k" (smerge-prev) "prev change" ) - ("j" (smerge-next) "next change") - ("u" (smerge-keep-upper) "keep upper") - ("l" (smerge-keep-lower) "keep lower") - ("q" nil "quit" :exit t)) -#+end_src -** Formatting -#+begin_src emacs-lisp -(use-package apheleia - :hook (prog-mode . apheleia-mode)) -#+end_src -** Flycheck (Syntax Checking) -#+begin_src emacs-lisp -(use-package flycheck - :config - (global-flycheck-mode +1)) -#+end_src -** Docker -#+begin_src emacs-lisp -(use-package docker - :ensure t - :bind ("C-c d" . docker)) -#+end_src -** Treemacs -#+begin_src emacs-lisp -(use-package treemacs - :defer t - :init - (with-eval-after-load 'winum - (define-key winum-keymap (kbd "M-0") #'treemacs-select-window)) - :config - (progn - (setq treemacs-collapse-dirs (if treemacs-python-executable 3 0) - treemacs-deferred-git-apply-delay 0.5 - treemacs-directory-name-transformer #'identity - treemacs-display-in-side-window t - treemacs-eldoc-display 'simple - treemacs-file-event-delay 2000 - treemacs-file-extension-regex treemacs-last-period-regex-value - treemacs-file-follow-delay 0.2 - treemacs-file-name-transformer #'identity - treemacs-follow-after-init t - treemacs-expand-after-init t - treemacs-find-workspace-method 'find-for-file-or-pick-first - treemacs-git-command-pipe "" - treemacs-goto-tag-strategy 'refetch-index - treemacs-header-scroll-indicators '(nil . "^^^^^^") - treemacs-hide-dot-git-directory t - treemacs-indentation 2 - treemacs-indentation-string " " - treemacs-is-never-other-window nil - treemacs-max-git-entries 5000 - treemacs-missing-project-action 'ask - treemacs-move-forward-on-expand nil - treemacs-no-png-images nil - treemacs-no-delete-other-windows t - treemacs-project-follow-cleanup nil - treemacs-persist-file (expand-file-name ".cache/treemacs-persist" user-emacs-directory) - treemacs-position 'left - treemacs-read-string-input 'from-child-frame - treemacs-recenter-distance 0.1 - treemacs-recenter-after-file-follow nil - treemacs-recenter-after-tag-follow nil - treemacs-recenter-after-project-jump 'always - treemacs-recenter-after-project-expand 'on-distance - treemacs-litter-directories '("/node_modules" "/.venv" "/.cask") - treemacs-project-follow-into-home nil - treemacs-show-cursor nil - treemacs-show-hidden-files t - treemacs-silent-filewatch nil - treemacs-silent-refresh nil - treemacs-sorting 'alphabetic-asc - treemacs-select-when-already-in-treemacs 'move-back - treemacs-space-between-root-nodes t - treemacs-tag-follow-cleanup t - treemacs-tag-follow-delay 1.5 - treemacs-text-scale nil - treemacs-user-mode-line-format nil - treemacs-user-header-line-format nil - treemacs-wide-toggle-width 70 - treemacs-width 35 - treemacs-width-increment 1 - treemacs-width-is-initially-locked t - treemacs-workspace-switch-cleanup nil) - - ;; The default width and height of the icons is 22 pixels. If you are - ;; using a Hi-DPI display, uncomment this to double the icon size. - ;;(treemacs-resize-icons 44) - - (treemacs-follow-mode t) - (treemacs-tag-follow-mode t) - (treemacs-project-follow-mode t) - (treemacs-filewatch-mode t) - (treemacs-fringe-indicator-mode 'always) - (when treemacs-python-executable - (treemacs-git-commit-diff-mode t)) - - (pcase (cons (not (null (executable-find "git"))) - (not (null treemacs-python-executable))) - (`(t . t) - (treemacs-git-mode 'deferred)) - (`(t . _) - (treemacs-git-mode 'simple))) - - (treemacs-hide-gitignored-files-mode nil)) - :bind - (:map global-map - ("M-0" . treemacs-select-window) - ("C-x t 1" . treemacs-delete-other-windows) - ("C-x t d" . treemacs-select-directory) - ("C-x t B" . treemacs-bookmark) - ("C-x t C-t" . treemacs-find-file) - ("C-x t M-t" . treemacs-find-tag))) - -(use-package treemacs-evil - :after (treemacs evil)) - -(use-package treemacs-magit - :after (treemacs magit)) - -(use-package treemacs-nerd-icons - :config - (treemacs-load-theme "nerd-icons")) -#+end_src -** Direnv -#+begin_src emacs-lisp - (when (eq system-type 'gnu/linux) - (use-package direnv - :config - (direnv-mode))) -#+end_src -* Languages -#+begin_src emacs-lisp -(message "Reached languages") -#+end_src -** HTML/CSS -#+begin_src emacs-lisp -(use-package web-mode - :hook (web-mode . eglot-ensure) - :mode ("\\.html\\'" - "\\.css\\'")) -#+end_src -** Javascript -#+begin_src emacs-lisp -(use-package js2-mode -:mode ("\\.js\\'" - "\\.jsx\\'") -:hook (js2-mode . eglot-ensure) -:config -(setq web-mode-markup-indent-offset 2) ; HTML -(setq web-mode-css-indent-offset 2) ; CSS -(setq web-mode-code-indent-offset 2) ; JS/JSX/TS/TSX -(setq web-mode-content-types-alist '(("jsx" . "\\.js[x]?\\'")))) -#+end_src -** Typescript -#+begin_src emacs-lisp - - (add-to-list 'auto-mode-alist '(".*\\.ts" . typescript-ts-mode)) - (add-to-list 'auto-mode-alist '(".*\\.tsx" . tsx-ts-mode)) - - (add-hook 'typescript-ts-mode-hook 'eglot-ensure) - (add-hook 'tsx-ts-mode-hook 'eglot-ensure) - - (setq treesit-language-source-alist - '((typescript "https://github.com/tree-sitter/tree-sitter-typescript" "master" "typescript/src" nil nil) - (tsx "https://github.com/tree-sitter/tree-sitter-typescript" "master" "tsx/src" nil nil))) -#+end_src -** Astro -#+begin_src emacs-lisp - (define-derived-mode astro-mode web-mode "astro") - (setq auto-mode-alist - (append '((".*\\.astro\\'" . astro-mode)) - auto-mode-alist)) - - (add-to-list 'eglot-server-programs - '(astro-mode . ("astro-ls" "--stdio" - :initializationOptions - (:typescript (:tsdk "./node_modules/typescript/lib"))))) -#+end_src -** C/C++ -#+begin_src emacs-lisp -(add-hook 'c-mode-hook 'eglot-ensure) -(add-hook 'c++-mode-hook 'eglot-ensure) -#+end_src -** C# -#+begin_src emacs-lisp - (add-hook 'csharp-mode-hook 'eglot-ensure) - (when (eq system-type 'gnu/linux) - (add-to-list 'eglot-server-programs - `(csharp-mode . ("OmniSharp" "-lsp")))) - - (use-package csproj-mode - :mode ("\\.csproj\\'")) - - (use-package dotnet - :hook (dotnet-mode . csharp-mode)) -#+end_src -** CMake -#+begin_src emacs-lisp -(use-package cmake-mode - :mode "CMakeLists.txt" - :hook (cmake-mode . eglot-ensure)) -#+end_src -** Lua -#+begin_src emacs-lisp -(use-package lua-mode - :mode "\\.lua\\'" - :hook (lua-mode . eglot-ensure)) -#+end_src -** Python -#+begin_src emacs-lisp -(use-package python-mode - :mode "\\.py\\'" - :hook (python-mode . eglot-ensure)) - -(use-package elpy -:after python-mode - -:custom -(elpy-rpc-python-command "python3") - -:config -(elpy-enable)) - -(use-package poetry - :config - (poetry-tracking-mode 1)) -#+end_src -** Yaml -#+begin_src emacs-lisp - (use-package yaml-mode - :hook (yaml-mode. eglot-ensure) - :mode ("\\.yml\\'" - "\\.yaml\\'")) -#+end_src -** Nix -#+begin_src emacs-lisp -(use-package nix-mode - :hook (nix-mode . eglot-ensure) - :mode "\\.nix\\'") -#+end_src -** Dart -#+begin_src emacs-lisp -(use-package dart-mode - :hook (dart-mode . eglot-ensure) -:mode "\\.dart\\'" ) -#+end_src -** Markdown -#+begin_src emacs-lisp -(use-package markdown-mode - :hook (markdown-mode . visual-line-mode)) - -(use-package markdown-preview-mode) -#+end_src -** GDScript -#+begin_src emacs-lisp -(use-package gdscript-mode - :hook (gdscript-mode . eglot-ensure) - :mode "\\.gd\\'") -#+end_src -** Rust -#+begin_src emacs-lisp - ;; (use-package rust-mode - ;; :hook (rust-mode . eglot-ensure) - ;; :mode "\\.rs\\'") - - ;; (use-package cargo-mode - ;; :hook - ;; (rust-mode . cargo-minor-mode) - ;; :config - ;; (setq compilation-scroll-output t)) - - (use-package rustic - :ensure t - :config - (setq rustic-format-on-save nil) - (setq rustic-lsp-client 'eglot) - :custom - (rustic-cargo-use-last-stored-arguments t)) -#+end_src -** Haskell -#+begin_src emacs-lisp - (use-package haskell-mode - :hook (haskell-mode . eglot-ensure) - :mode "\\.hs'") -#+end_src -** Go -#+begin_src emacs-lisp - (use-package go-mode - :mode "\\.go\\'" - :hook (go-mode . eglot-ensure)) -#+end_src -* Social -#+begin_src emacs-lisp -(message "Reached social") -#+end_src -** Elcord (Discord rich precense) -#+begin_src emacs-lisp -(use-package elcord - :init - (setq elcord-display-buffer-details nil) - (setq elcord-use-major-mode-as-main-icon t) - ) -#+end_src -** Telegram -does NOT WORK ON WINDOWS -#+begin_src emacs-lisp -(unless (eq system-type 'windows-nt) - (use-package telega)) -#+end_src -** IRC -Will configure later -#+begin_src emacs-lisp -(use-package rcirc) -#+end_src -** RSS -Will configure later, (use elfeed protocol ok ty) -#+begin_src emacs-lisp - (use-package elfeed - :config - (setq elfeed-use-curl t) - (elfeed-set-timeout 36000) - ) - - (use-package elfeed-protocol - :config - ;; setup feeds - (setq elfeed-protocol-fever-update-unread-only nil) - (setq elfeed-protocol-fever-fetch-category-as-tag t) - (setq elfeed-protocol-feeds '(("fever+https://sako@rss.sako.box" - :api-url "https://rss.sako.box/fever/" - :password (password-store-get "SelfHosted/rss.sako.box/fever")))) - - ;; enable elfeed-protocol - (setq elfeed-protocol-enabled-protocols '(fever)) - (elfeed-protocol-enable)) -#+end_src -** Matrix -Ill set this up later as well -#+begin_src emacs-lisp - (use-package ement - :commands ement-connect - :custom - (ement-notify-dbus-p nil) ;; Turn off notifications - (ement-sessions-file "~/.cache/ement.el") - (ement-room-list-default-keys - '(;; Group all invitations (this group will appear first since the rooms are - ;; already sorted first). - ((membership :status 'invite)) - - ;; Group all left rooms (this group will appear last, because the rooms are already - ;; sorted last). - ((membership :status 'leave)) - - ;; Group all favorite rooms, which are already sorted first. - (favourite) - - ;; Group all low-priority rooms, which are already sorted last. - (low-priority) - - ;; Group other rooms which are unread. - (unread) - (people) - freshness))) -#+end_src -** Subsonic -#+begin_src emacs-lisp -(use-package subsonic) -#+end_src -** EMMS -Emacs music player lmfao -#+begin_src emacs-lisp - (use-package emms - :config - (emms-all) - (setq emms-player-list '(emms-player-mpd)) - (setq emms-info-functions '(emms-info-mod)) - (setq emms-source-file-default-directory "~/music") - ;; TODO Keybinds maybe - ) -#+end_src -** GPTel -its over the machines took over guys can i get my likes now -#+begin_src emacs-lisp - (use-package gptel - :config - (gptel-make-ollama "Ollama" - :host "localhost:11434" - :stream t - :models '("mistral:latest"))) -#+end_src -** mu4e -GNU patch review metho dor sometihng idk -#+begin_src emacs-lisp - (use-package mu4e - :config - - ;; mu4e syncing issue with isync - (setq mu4e-change-filenames-when-moving t) - - ;; sending mail - (setq message-send-mail-function 'smtpmail-send-it) - - (setq mu4e-update-interval (* 10 60)) - (setq mu4e-get-mail-command "mbsync -a") - (setq mu4e-maildir "~/Mail") - - (setq outlook-mail-address - (string-trim (shell-command-to-string "pass mail | awk 'BEGIN {ORS=\"\"} FNR == 2{gsub(\"login: \", \"\"); gsub(/ /, \"\"); print}'"))) - - (defvar proton-mail-address nil) - - (defun get-proton-mail-address-from-pass (command) - "Execute COMMAND, concatenate its output with 'hello', and store it in my-greeting." - (let ((output (shell-command-to-string command))) - ;; Trim whitespace from the output - (setq output (string-trim output)) - ;; Concatenate 'hello' with the command output - (setq my-greeting (concat "@proton.me" output)))) - - (get-proton-mail-address-from-pass "pass Proton\ Account | awk 'BEGIN {ORS=\"\"} FNR == 2{gsub(\"login: \", \"\"); gsub(/ /, \"\"); print}'") - - (setq mu4e-contexts - (list - ;; outlook - (make-mu4e-context - :name "Outlook" - :match-func - (lambda (msg) - (when msg - (string-prefix-p "/Outlook" (mu4e-message-field msg :maildir)))) - :vars `((user-mail-address . ,outlook-mail-address) - (user-full-name . "Sako") - (mu4e-drafts-folder . "/Outlook/Drafts") - (mu4e-sent-folder . "/Outlook/Sent") - (mu4e-refile-folder . "/Outlook/Inbox") - (mu4e-trash-folder . "/Outlook/Deleted"))) - (make-mu4e-context - :name "Proton" - :match-func - (lambda (msg) - (when msg - (string-prefix-p "/Proton" (mu4e-message-field msg :maildir)))) - :vars `((user-mail-address . ,proton-mail-address) - (user-full-name . "Sako") - (mu4e-drafts-folder . "/Proton/Drafts") - (mu4e-sent-folder . "/Proton/Sent") - (mu4e-refile-folder . "/Proton/Inbox") - (mu4e-trash-folder . "/Proton/Trash"))) - )) - ) -#+end_src -* Org -#+begin_src emacs-lisp -(message "Reached Org") -#+end_src -** Org mode configuration -#+begin_src emacs-lisp - (use-package org - :hook (org-mode . org-indent-mode) - :config - (setq org-ellipsis " ↓") - (setq org-agenda-start-with-log-mode t) - (setq org-log-done 'time) - (setq org-log-into-drawer t) - - ;; habits, useless for now though - ;; (require 'org-habit) - ;; (add-to-list 'org-modules 'org-habit) - ;; (setq org-habit-graph-column 60) - - ;; archive - (setq org-refile-targets - '(("archive.org" :maxlevel . 1))) - - ;; make sure to save everything after refiling - (advice-add 'org-refile :after 'org-save-all-org-buffers) - - ;; org agenda - (setq org-agenda-files - '("~/org/tasks.org" - "~/org/school.org" - "~/org/daily.org" - "~/org/irl.org" - "~/org/work.org")) - - ;; follow links - (setq org-return-follows-link t) - - ;; hide leading stars - (setq org-hide-leading-stars t) - (setq org-hide-emphasis-markers nil) - - ;; templates - (require 'org-tempo) - - ;; this'll come in handly later - (add-to-list 'org-structure-template-alist '("sh" . "src shell")) - (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp")) - (add-to-list 'org-structure-template-alist '("py" . "src python")) - - ;; more options - (setq org-todo-keywords - '((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d!)") - (sequence "BACKLOG(b)" "PLAN(p)" "READY(r)" "ACTIVE(a)" "REVIEW(v)" "WAIT(w@/!)" "HOLD(h)" "|" "COMPLETED(c)" "CANCELED(k@)"))) - - ;; this is really useful - (setq org-startup-with-inline-images t) - - ;; i hope i actually use this eventually - (setq org-capture-templates - `(("t" "Tasks") - ("tt" "Task" entry (file+olp "~/org/tasks.org" "captured") - "* TODO %?\n %U\n %a\n %i" :empty-lines1))) - ) - - -#+end_src -** Org Roam -#+begin_src emacs-lisp - (use-package org-roam - :custom - (org-roam-directory "~/org/notes") - :bind (("C-c n l" . org-roam-buffer-toggle) - ("C-c n f" . org-roam-node-find) - ("C-c n i" . org-roam-node-insert)) - :config - (org-roam-setup)) -#+end_src -** Org-wild-notifier -#+begin_src emacs-lisp -(use-package org-wild-notifier - :config - (org-wild-notifier-mode)) -#+end_src -** Org-Pomodoro -#+begin_src emacs-lisp -(use-package org-pomodoro) -#+end_src -** PDF-Tools -Export and then view with emacs :) -#+begin_src emacs-lisp -(use-package pdf-tools) -#+end_src -* EXWM -I'm scared -#+begin_src emacs-lisp - - (defcustom is-exwm nil - "Toggle if EXWM is being used" - :type 'boolean) - - (when (eq system-type 'gnu/linux) - (when is-exwm - (use-package exwm - :config - (set-frame-parameter nil 'alpha '(90 . 90)) - (add-to-list 'default-frame-alist '(alpha . (90 . 90))) - - (defun sakomacs/exwm-init-hook () - ;; background - (call-process-shell-command "feh --bg-fill ~/background.png" nil 0) - ;; (set-frame-parameter nil 'alpha 90) - ;; (call-process-shell-command "~/.config/polybar/startpolybar" nil 0) - (call-process-shell-command "~/.config/picom/startpicom" nil 0) - ;; startup - (call-process-shell-command "nm-applet" nil 0) - (call-process-shell-command "blueman-applet" nil 0) - ;; (call-process-shell-command "nextcloud" nil 0) - ;; (call-process-shell-command "bitwarden" nil 0) - (call-process-shell-command "flameshot" nil 0) - - ;; battery - (display-battery-mode) - ;; show time on the modeline - (setq display-time-default-load-average nil) - (setq display-time-24hr-format t) - (display-time-mode t) - ;; shrink fringe to 1px - (fringe-mode 1) - ) - - ;; background - ;; todo turn this info a function - (add-hook 'exwm-init-hook 'sakomacs/exwm-init-hook) - ;; startup - ;; workspaces - (setq exwm-workspace-number 5) - - - (require 'exwm-systemtray) - (exwm-systemtray-enable) - - ;; polybar - (defvar sakomacs/polybar-process nil - "Holds the process of the running Polybar instance, if any") - - (server-start) - - (defun sakomacs/kill-panel () - (interactive) - (when sakomacs/polybar-process - (ignore-errors - (kill-process sakomacs/polybar-process))) - (setq sakomacs/polybar-process nil)) - - (defun sakomacs/start-panel () - (interactive) - (sakomacs/kill-panel) - (setq sakomacs/polybar-process (start-process-shell-command "polybar" nil "polybar panel"))) - - (defun sakomacs/send-polybar-hook (module-name hook-index) - (start-process-shell-command "polybar-msg" nil (format "polybar-msg hook %s %s" module-name hook-index))) - - (defun sakomacs/send-polybar-exwm-workspace () - (sakomacs/send-polybar-hook "exwm-workspace" 1)) - - ;; Update panel indicator when workspace changes - (add-hook 'exwm-workspace-switch-hook #'sakomacs/send-polybar-exwm-workspace) - - - ;; make the buffer names better - (add-hook 'exwm-update-class-hook - (lambda () - (unless (or (string-prefix-p "sun-awt-X11-" exwm-instance-name) - (string= "gimp" exwm-instance-name)) - (exwm-workspace-rename-buffer exwm-class-name)))) - (add-hook 'exwm-update-title-hook - (lambda () - (when (or (not exwm-instance-name) - (string-prefix-p "sun-awt-X11-" exwm-instance-name) - (string= "gimp" exwm-instance-name)) - (exwm-workspace-rename-buffer exwm-title)))) - - ;; always use these keys in emacs - (setq exwm-input-prefix-keys - '(?\C-x - ?\C-u - ?\C-h - ?\M-x - ?\M-` - ?\M-& - ?\M-: - ?\C-\M-j ;; Buffer list - ?\C-\ )) ;; Ctrl+Space - - (setq exwm-input-stimulation-keys - '( - ;; cut/paste. - ([?\C-w] . [?\C-x]) - ([?\M-w] . [?\C-c]) - ([?\C-y] . [?\C-v]))) - - - ;; Ctrl+/3Q will enable the next key to be sent directly - (define-key exwm-mode-map [?\C-q] 'exwm-input-send-next-key) - ;; app launcher and fullscreen - (exwm-input-set-key (kbd "s-SPC") 'app-launcher-run-app) - (exwm-input-set-key (kbd "s-f") 'exwm-layout-toggle-fullscreen) - (exwm-input-set-key (kbd "s-") 'vterm) - - ;; kill apps - (exwm-input-set-key (kbd "s-q") #'kill-current-buffer) - - ;; Set up global key bindings. These always work, no matter the input state! - ;; Keep in mind that changing this list after EXWM initializes has no effect. - (setq exwm-input-global-keys - `( - ;; Reset to line-mode (C-c C-k switches to char-mode via exwm-input-release-keyboard) - ([?\s-r] . exwm-reset) - - ;; Move between windows - ([s-left] . windmove-left) - ([s-right] . windmove-right) - ([s-up] . windmove-up) - ([s-down] . windmove-down) - - ;; Launch applications via shell command - ([?\s-&] . (lambda (command) - (interactive (list (read-shell-command "$ "))) - (start-process-shell-command command nil command))) - - ;; Switch workspace - ([?\s-w] . exwm-workspace-switch) - - ;; 's-N': Switch to certain workspace with Super (Win) plus a number key (0 - 9) - ,@(mapcar (lambda (i) - `(,(kbd (format "s-%d" i)) . - (lambda () - (interactive) - (exwm-workspace-switch-create ,i)))) - (number-sequence 0 9)))) - ) - - (use-package desktop-environment - :after exwm - :config (desktop-environment-mode) - :custom - (desktop-environment-brightness-small-increment "2%+") - (desktop-environment-brightness-small-decrement "2%-") - (desktop-environment-brightness-normal-increment "5%+") - (desktop-environment-brightness-normal-decrement "5%-")) - )) -#+end_src -* End -#+begin_src elisp - (message "Welcome to Emacs!") - - ;; EOF -#+end_src +#+title: EMACS 2 +#+PROPERTY: header-args:emacs-lisp :tangle yes :tangle init.el +* Welcome! +#+begin_src emacs-lisp +;; -*- lexical-binding: t; -*- +#+end_src +* Package Setup +#+begin_src emacs-lisp + (message "Reached package setup") + + (require `package) + + (setq package-archives `(("mepla" . "https://melpa.org/packages/") + ("org" . "https://orgmode.org/elpa/") + ("elpa" . "https://elpa.gnu.org/packages/"))) + (package-initialize) + (unless (package-installed-p 'use-package) + (progn + (package-refresh-contents) + (package-install 'use-package))) + + (require 'use-package) + (setq use-package-always-ensure t) + + ;; TODO add better detection to this + (when (eq system-type 'windows-nt) + (message "setting up straight.el") + (defvar bootstrap-version) + (let ((bootstrap-file + (expand-file-name + "straight/repos/straight.el/bootstrap.el" + (or (bound-and-true-p straight-base-dir) + user-emacs-directory))) + (bootstrap-version 7)) + (unless (file-exists-p bootstrap-file) + (with-current-buffer + (url-retrieve-synchronously + "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el" + 'silent 'inhibit-cookies) + (goto-char (point-max)) + (eval-print-last-sexp))) + (load bootstrap-file nil 'nomessage)) + (setq straight-use-package-by-default t)) +#+end_src +* Make Emacs faster +#+begin_src emacs-lisp +(message "Speeding up") +#+end_src +** Avoid garbage collection at startup +#+begin_src emacs-lisp +(use-package gcmh + :init + (setq gcmh-idle-delay 5) + (setq gcmh-high-cons-threshold (* 16 1024 1024)) + :config + (gcmh-mode)) +#+end_src +** Set garbage collection to be further back +#+begin_src emacs-lisp +(setq gc-cons-threshold most-positive-fixnum) +#+end_src +** Unset file-name-handler-alist +#+begin_src emacs-lisp +(defvar sakomacs--file-name-handler-alist file-name-handler-alist) +(setq file-name-handler-alist nil) + +;; Alternatively, restore it even later: +(add-hook 'emacs-startup-hook + (lambda () + (setq file-name-handler-alist sakomacs--file-name-handler-alist))) +#+end_src +** Reset gc once init has finished +#+begin_src emacs-lisp + (defun doom-defer-garbage-collection-h () + "Disable garbage collection." + (setq gc-cons-threshold most-positive-fixnum)) + +(defun doom-restore-garbage-collection-h () + "Restore garbage collection." + (run-at-time + 1 nil (lambda () (setq gc-cons-threshold 16777216)))) + +(add-hook 'minibuffer-setup-hook #'doom-defer-garbage-collection-h) +(add-hook 'minibuffer-exit-hook #'doom-restore-garbage-collection-h) +#+end_src +** Read more +#+begin_src emacs-lisp +(setq read-process-output-max (* 1024 1024)) ;; 1mb +#+end_src +* Keybinds +Ill use this later eventually +#+begin_src emacs-lisp +(message "Got to keybinds") +#+end_src +** Make emacs more human +#+begin_src emacs-lisp +(global-set-key (kbd "") 'keyboard-escape-quit) +#+end_src +* Core +#+begin_src elisp + (message "Reached core.") +#+end_src +** Encoding +#+begin_src emacs-lisp +(setq utf-translate-cjk-mode nil) ; disable CJK coding/encoding (Chinese/Japanese/Korean characters) +(set-language-environment 'utf-8) +(set-keyboard-coding-system 'utf-8) ; For old Carbon emacs on OS X only +(setq locale-coding-system 'utf-8) +(set-default-coding-systems 'utf-8) +(set-terminal-coding-system 'utf-8) +(set-selection-coding-system + (if (eq system-type 'windows-nt) + 'utf-16-le ;; https://rufflewind.com/2014-07-20/pasting-unicode-in-emacs-on-windows + 'utf-8)) +(prefer-coding-system 'utf-8) +#+end_src +** Cleanup .emacs.d +#+begin_src emacs-lisp +(setq backup-directory-alist '(("." . "~/.emacs.d/backup")) +backup-by-copying t +version-control t +delete-old-versions t +kept-new-versions 20 +kept-old-versions 5) + +(use-package no-littering + :config + (setq custom-file (if (boundp 'server-socket-dir) + (expand-file-name "custom.el" server-socket-dir) + (no-littering-expand-etc-file-name "custom.el"))) + (when (file-exists-p custom-file) + (load custom-file t)) + + ;; Don't litter project folders with backup files + (let ((backup-dir (no-littering-expand-var-file-name "backup/"))) + (make-directory backup-dir t) + (setq backup-directory-alist + `(("\\`/tmp/" . nil) + ("\\`/dev/shm/" . nil) + ("." . ,backup-dir)))) + + (setq auto-save-default nil) + + ;; Tidy up auto-save files + (setq auto-save-default nil) + (let ((auto-save-dir (no-littering-expand-var-file-name "auto-save/"))) + (make-directory auto-save-dir t) + (setq auto-save-file-name-transforms + `(("\\`/[^/]*:\\([^/]*/\\)*\\([^/]*\\)\\'" + ,(concat temporary-file-directory "\\2") t) + ("\\`\\(/tmp\\|/dev/shm\\)\\([^/]*/\\)*\\(.*\\)\\'" "\\3") + ("." ,auto-save-dir t))))) + +;; no-littering doesn't set this by default so we must place +;; auto save files in the same path as it uses for sessions +(setq auto-save-file-name-transforms + `((".*" ,(no-littering-expand-var-file-name "auto-save/") t))) +#+end_src +** Native Compilation +#+begin_src emacs-lisp +(setq native-comp-async-report-warnings-errors nil) + +(add-to-list 'native-comp-eln-load-path (expand-file-name "eln-cache/" user-emacs-directory)) +#+end_src +** Emacs settings +#+begin_src emacs-lisp +(setq inhibit-startup-message t) + +;; make emacs look a little more cleaner +(scroll-bar-mode -1) +(tool-bar-mode -1) +(tooltip-mode -1) +(set-fringe-mode 10) +(menu-bar-mode -1) + +;; this is really annoying i hate it +(setq visible-bell nil) + +;; -- core keybinds and packages -- +(repeat-mode 1) + +(column-number-mode) + +(dolist (mode '(text-mode-hook + prog-mode-hook + conf-mode-hook)) + (add-hook mode (lambda () (display-line-numbers-mode 1)))) +#+end_src +** Core Keybinds +#+begin_src emacs-lisp +(repeat-mode 1) + +(column-number-mode) + +(dolist (mode '(text-mode-hook + prog-mode-hook + conf-mode-hook)) + (add-hook mode (lambda () (display-line-numbers-mode 1)))) +#+end_src +** Appearance +#+begin_src emacs-lisp + ;; (use-package doom-themes + ;; :config + ;; (load-theme 'doom-sourcerer t)) + + ;; (use-package grandshell-theme + ;; :config + ;; (load-theme 'grandshell t)) + + ;; (use-package ef-themes + ;; :config + ;; (load-theme 'ef-dark t)) + + ;; (use-package kanagawa-themes + ;; :config + ;; (load-theme 'kanagawa-dragon t)) + + ;; (use-package klere-theme + ;; :config + ;; (load-theme 'klere t)) + + (use-package kaolin-themes + :config + (load-theme 'kaolin-shiva t)) + + ;; emacsclient things + (setq frame-resize-pixelwise t) + ;; ui settings apparently go below + (setq default-frame-alist '((font . "JetBrainsMono NF") + '(vertical-scroll-bars . nil) + '(horizontal-scroll-bars . nil))) + + ;; GO AWAY + (defun my/disable-scroll-bars (frame) + (modify-frame-parameters frame + '((vertical-scroll-bars . nil) + (horizontal-scroll-bars . nil)))) + (add-hook 'after-make-frame-functions 'my/disable-scroll-bars) + + + ;; y/n is better than yes/no + (fset 'yes-or-no-p 'y-or-n-p) + + ;; font + (set-face-attribute 'default nil + :font "JetBrainsMono NF" + :weight 'light + :height 125) +#+end_src +** Emacs Client +#+begin_src emacs-lisp +(setq frame-resize-pixelwise t) +;; ui settings apparently go below +(setq default-frame-alist '((font . "JetBrainsMono NF") + '(vertical-scroll-bars . nil) + '(horizontal-scroll-bars . nil))) +#+end_src +** Modeline +#+begin_src emacs-lisp + ;; (use-package nerd-icons + ;; :custom + ;; (nerd-icons-font-family "JetBrainsMono NF")) + ;; (use-package doom-modeline + ;; :custom + ;; (doom-modeline-height 35) + ;; (doom-modeline-modal-modern-icon nil) + ;; :init (doom-modeline-mode 1)) +#+end_src +** Editor Configuration +#+begin_src emacs-lisp +(use-package super-save + :config + (super-save-mode +1) + (setq super-save-auto-save-when-idle t)) + +;; revert dired and other buffers +(setq global-auto-revert-non-file-buffers t) + +;; revert buffers when file has been changed +(global-auto-revert-mode 1) + +;; popups and stuff +(use-package popper + :bind (("C-M-'" . popper-toggle) + ("M-'" . popper-cycle) + ("C-M-\"" . popper-toggle-type)) + :custom + (popper-window-height 12) + (popper-reference-buffers '(eshell-mode + vterm-mode + geiser-repl-mode + help-mode + grep-mode + helpful-mode + compilation-mode)) + :config + (popper-mode 1)) +#+end_src +** Helpful +#+begin_src emacs-lisp +(use-package helpful + :custom + (counsel-describe-function-function #'helpful-callable) + (counsel-describe-variable-function #'helpful-variable) + :bind (([remap describe-function] . helpful-function) + ([remap describe-symbol] . helpful-symbol) + ([remap describe-variable] . helpful-variable) + ([remap describe-command] . helpful-command) + ([remap describe-key] . helpful-key))) +#+end_src +** Which Key +#+begin_src emacs-lisp +;; incase i get lost +(use-package which-key + :init (which-key-mode) + :diminish which-key-mode + :config + (setq which-key-idle-delay 1)) +#+end_src +** Alerts +#+begin_src emacs-lisp +(when (eq system-type 'windows-nt) + (use-package alert + :commands (alert) + :config (setq alert-default-style 'toast)) + + (use-package alert-toast + :after alert)) +#+end_src +** Daemon +#+begin_src emacs-lisp +(if (eq system-type 'windows-nt) + (setq server-socket-dir "~/.emacs.d/server")) +(server-start) +#+end_src +* Keys +#+begin_src emacs-lisp +(message "got to keys setup") +#+end_src +** General +#+begin_src emacs-lisp + ;; (use-package general + ;; :config + ;; (general-create-definer sk/leader-keys + ;; :keymaps '(normal insert visual emacs) + ;; :prefix "SPC" + ;; :global-prefix "C-SPC") + + ;; (sk/leader-keys + ;; ;; code + ;; "c" '(:ignore c :which-key "code") + ;; "cc" '(compile :which-key "compile") + ;; "cC" '(recompile :which-key "compile") + ;; "cX" '(lsp-treeemacs-errors-list :which-ley "list errors") + ;; ;; toggles + ;; "t" '(:ignore t :which-key "toggles") + ;; "tt" '(counsel-load-theme :which-key "choose theme") + ;; "ts" '(hydra-text-scale/body :which-key "scale text") + ;; ;; search + ;; "s" '(:ignore s :which-key "search") + ;; "sb" '(swiper :which-key "search buffer") + ;; ;; insert + ;; "i" '(:ignore i :which-key "insert") + ;; "ie" '(emoji-search :which-key "Emoji") + ;; ;; project + ;; "p" '(:ignore p :which-key "projects") + ;; "pp" '(project-switch-project :which-key "open project") + ;; "pk" '(project-kill-buffers :which-key "close project") + ;; "pt" '(magit-todos-list :which-key "list project todos") + ;; "po" '(project-find-file :which-key "find file") + ;; "pc" '(project-compile :which-key "compile project") + ;; ;; open + ;; "o" '(:ignore o :which-key "open") + ;; "op" '(treemacs :which-key "treemacs") + ;; "oP" '(treemacs-find-file :which-key "treemacs find file") + ;; "oe" '(eshell :which-key "eshell") + ;; "ov" '(vterm :which-key "vterm") + ;; "or" '(elfeed :which-key "rss") + ;; ;; notes + ;; "n" '(:ignore o :which-key "notes") + ;; "na" '(org-agenda :which-key "agenda") + ;; "nf" '(org-roam-node-find :which-key "find node") + ;; "nc" '(org-capture :which-key "capture") + ;; "np" '(org-pomodoro :which-key "pomodoro") + ;; "ne" '(:ignore ne :which-key "export") + ;; "nep" '(org-latex-export-to-pdf :which-key "pdf") + ;; ;; quit + ;; "q" '(:ignore q :which-key "quit") + ;; "qq" '(delete-frame :which-key "close emacs") + ;; "qK" '(kill-emacs :which-key "quit emacs") + ;; ;; git + ;; "g" '(:ignore g :which-key "git") + ;; "gs" '(magit-status :which-key "status") + ;; "gc" '(:ignore gc :which-key "create") + ;; "gcr" '(magit-init :which-key "init repo") + ;; "gcR" '(magit-clone :which-key "clone repo") + ;; "gcc" '(magit-commit-create :which-key "commit") + ;; "gci" '(forge-create-issue :which-key "issue") + ;; "gcp" '(forge-create-pullreq :which-key "pull request") + ;; ;; mail + ;; "m" '(mu4e :which-key "mu4e"))) + +#+end_src +** Evil +#+begin_src emacs-lisp + + ;; (use-package evil + ;; :init + ;; ;; Pre-load configuration + ;; (setq evil-want-integration t) + ;; (setq evil-want-keybinding nil) + ;; (setq evil-want-C-u-scroll t) + ;; (setq evil-want-C-i-jump nil) + ;; (setq evil-respect-visual-line-mode t) + ;; (setq evil-undo-system 'undo-tree) + ;; :config + ;; (evil-mode 1) + + ;; ;; use emacs state for these mods + ;; (dolist (mode '(custom-mode + ;; eshell-mode + ;; git-rebase-mode + ;; erc-mode + ;; circe-server-mode + ;; circe-chat-mode + ;; circe-query-mode + ;; term-mode)) + ;; (add-to-list 'evil-emacs-state-modes mode)) + + ;; (defun sk/dont-arrow-me-bro () + ;; (interactive) + ;; (message "STOP USING THE ARROW KEYS!!!!!!!!!!!!!!!!!!!!!!!")) + + ;; ;; Disable arrow keys in normal and visual modes + ;; (define-key evil-normal-state-map (kbd "") 'sk/dont-arrow-me-bro) + ;; (define-key evil-normal-state-map (kbd "") 'sk/dont-arrow-me-bro) + ;; (define-key evil-normal-state-map (kbd "") 'sk/dont-arrow-me-bro) + ;; (define-key evil-normal-state-map (kbd "") 'sk/dont-arrow-me-bro) + ;; (evil-global-set-key 'motion (kbd "") 'sk/dont-arrow-me-bro) + ;; (evil-global-set-key 'motion (kbd "") 'sk/dont-arrow-me-bro) + ;; (evil-global-set-key 'motion (kbd "") 'sk/dont-arrow-me-bro) + ;; (evil-global-set-key 'motion (kbd "") 'sk/dont-arrow-me-bro) + + ;; (evil-set-initial-state 'messages-buffer-mode 'normal) + ;; (evil-set-initial-state 'dashboard-mode 'normal)) + + ;; (use-package evil-collection + ;; :after evil + ;; :custom + ;; (evil-collection-outline-bind-tab-p nil) + ;; :config + ;; ;; Is this a bug in evil-collection? + ;; (setq evil-collection-company-use-tng nil) + ;; (delete 'lispy evil-collection-mode-list) + ;; (delete 'org-present evil-collection-mode-list) + ;; ;; (delete 'mu4e evil-collection-mode-list) + ;; ;; (delete 'mu4e-conversation evil-collection-mode-list) + ;; (evil-collection-init)) + + ;; (use-package evil-org + ;; :after (evil org) + ;; :hook ((org-mode . evil-org-mode) + ;; (org-agenda-mode . evil-org-mode)) + ;; :config + ;; (require 'evil-org-agenda) + ;; (evil-org-set-key-theme '(navigation todo insert textobjects additional)) + ;; (evil-org-agenda-set-keys)) + + ;; (use-package evil-nerd-commenter + ;; :bind ("M-/" . evilnc-comment-or-uncomment-lines)) + + ;; (with-eval-after-load 'org + ;; (evil-define-key '(normal insert visual) org-mode-map (kbd "C-j") 'org-next-visible-heading) + ;; (evil-define-key '(normal insert visual) org-mode-map (kbd "C-k") 'org-previous-visible-heading) + ;; (evil-define-key '(normal insert visual) org-mode-map (kbd "M-j") 'org-metadown) + ;; (evil-define-key '(normal insert visual) org-mode-map (kbd "M-k") 'org-metaup)) +#+end_src +* Interface +#+begin_src emacs-lisp +(message "Got to interface") +#+end_src +** Hydra +#+begin_src emacs-lisp +(use-package hydra) +#+end_src +** Vertico +#+begin_src emacs-lisp + (use-package vertico + :bind (:map vertico-map + ("C-j" . vertico-next) + ("C-k" . vertico-previous) + ("C-f" . vertico-exit-input) + :map minibuffer-local-map + ("M-h" . vertico-directory-up)) + :custom + (vertico-cycle t) + + :hook (rfn-eshadow-update-overlay . vertico-directory-tidy) + :init + (require 'vertico-directory) + (vertico-mode)) +#+end_src +** Marginalia +#+begin_src emacs-lisp +(use-package marginalia + :after vertico + :ensure t + :custom + (marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil)) + :init + (marginalia-mode)) +#+end_src +** Consult +#+begin_src emacs-lisp +(use-package consult + :bind (("C-s" . consult-line) + ("C-M-l" . consult-imenu) + ("C-M-j" . consult-buffer) + ("C-x C-b" . consult-buffer) + :map minibuffer-local-map + ("C-r" . consult-history))) + + +(use-package consult-dir + :bind (("C-x C-d" . consult-dir) + :map vertico-map + ("C-x C-d" . consult-dir) + ("C-x C-j" . consult-dir-jump-file)) + + :custom + (consult-dir-project-list-function nil)) +#+end_src +** Orderless +#+begin_src emacs-lisp +(use-package orderless + :config + (orderless-define-completion-style orderless+initialism + (orderless-matching-styles '(orderless-initialism + orderless-literal + orderless-regexp))) + + (setq completion-styles '(orderless) + completion-category-defaults nil + orderless-matching-styles '(orderless-literal orderless-regexp) + completion-category-overrides + '((file (styles partial-completion))))) +#+end_src +** Embark +#+begin_src emacs-lisp + (use-package embark + :after vertico + :bind (("C-." . embark-act) + ("M-." . embark-dwim) + :map minibuffer-local-map + ("C-d" . embark-act) + :map embark-region-map + ("D" . denote-region)) + + :config + ;; Remove the mixed indicator to prevent the popup from being displayed + ;; automatically + (delete #'embark-mixed-indicator embark-indicators) + (add-to-list 'embark-indicators 'embark-minimal-indicator) + + ;; Use Embark to show command prefix help + (setq prefix-help-command #'embark-prefix-help-command)) + + (use-package embark-consult + :after embark) + +#+end_src +** Corfu +#+begin_src emacs-lisp + (use-package corfu + :bind (:map corfu-map + ("C-j" . corfu-next) + ("C-k" . corfu-previous) + ("TAB" . corfu-insert) + ([tab] . corfu-insert) + ("C-f" . corfu-insert)) + :custom + (corfu-cycle t) + (corfu-auto t) + (corfu-preview-current nil) + (corfu-quit-at-boundary t) + (corfu-quit-no-match t) + (corfu-min-chars 3) + (corfu-auto-delay 0) + (corfu-auto-prefix 0) + :init + (global-corfu-mode) + + (defun corfu-enable-in-minibuffer () + "Enable Corfu in the minibuffer if `completion-at-point' is bound." + (when (where-is-internal #'completion-at-point (list (current-local-map))) + (setq-local corfu-auto nil) ;; Enable/disable auto completion + (setq-local corfu-echo-delay nil ;; Disable automatic echo and popup + corfu-popupinfo-delay nil) + (corfu-mode 1))) + + (add-hook 'minibuffer-setup-hook #'corfu-enable-in-minibuffer)) +#+end_src +** Dashboard +#+begin_src emacs-lisp + (use-package dashboard + :init + (setq initial-buffer-choice 'dashboard-open) + ;; Set the title + (setq dashboard-banner-logo-title "Welcome to Emacs!") + (setq dashboard-image-banner-max-height 100) + ;; Set the banner + (setq dashboard-startup-banner '"~/.emacs.d/icon.png") + (setq dashboard-center-content t) + (setq dashboard-vertically-center-content t) + (setq dashboard-show-shortcuts nil) + + ;; nerd icons + (setq dashboard-display-icons-p t) ; display icons on both GUI and terminal + (setq dashboard-icon-type 'nerd-icons) ; use `nerd-icons' package + + ;; list stuff + (setq dashboard-items '((projects . 3))) + :config + (dashboard-setup-startup-hook)) +#+end_src +* Auth +#+begin_src emacs-lisp +(message "Reached auth") +#+end_src +** Pinentry +#+begin_src emacs-lisp + (unless (eq system-type 'windows-nt) + (use-package pinentry + :config + (setq epa-pinentry-mode 'loopback) + (pinentry-start)) + ) +#+end_src +** Password-Store +#+begin_src emacs-lisp + (use-package password-store + :bind (("C-c p p" . password-store-copy) + ("C-c p i" . password-store-insert) + ("C-c p g" . password-store-generate)) + :config + (setq password-store-password-length 12)) + + (use-package pass) + + (auth-source-pass-enable) +#+end_src +** OAuth2 +this should be useful later +#+begin_src emacs-lisp +(use-package oauth2 + :ensure t) +#+end_src +* Shell +#+begin_src emacs-lisp +(message "Reached shell") +#+end_src +** EShell +#+begin_src emacs-lisp +(defun sk/configure-eshell () + ;; Save command history when commands are entered + (add-hook 'eshell-pre-command-hook 'eshell-save-some-history) + + ;; Truncate buffer for performance + (add-to-list 'eshell-output-filter-functions 'eshell-truncate-buffer) + + ;; Bind some useful keys for evil-mode + (evil-define-key '(normal insert visual) eshell-mode-map (kbd "C-r") 'counsel-esh-history) + (evil-define-key '(normal insert visual) eshell-mode-map (kbd "") 'eshell-bol) + (evil-normalize-keymaps) + + (setq eshell-history-size 10000 + eshell-buffer-maximum-lines 10000 + eshell-hist-ignoredups t + eshell-scroll-to-bottom-on-input t)) + +(use-package eshell-git-prompt) + + + (add-hook 'eshell-first-time-mode 'sakomacs/configure-eshell) + + (with-eval-after-load 'esh-opt + (setq eshell-destroy-buffer-when-process-dies t) + (setq eshell-visual-commands '("htop" "zsh" "vim")) + + (eshell-git-prompt-use-theme 'powerline)) +#+end_src +** VTerm +#+begin_src emacs-lisp + (use-package vterm + :bind ("" . vterm) + :commands vterm + :config + (setq vterm-max-scrollback 10000)) +#+end_src +* Dev +#+begin_src emacs-lisp +(message "Reached dev") +#+end_src +** {} and () matching +#+begin_src emacs-lisp +(use-package smartparens + :hook (prog-mode . smartparens-mode) + :config + (sp-use-smartparens-bindings)) + +(use-package rainbow-delimiters + :hook (prog-mode . rainbow-delimiters-mode)) +#+end_src +** Compilation +#+begin_src emacs-lisp +(setq compilation-scroll-output t) + +(setq compilation-environment '("TERM=xterm-256color")) + +(defun sk/advice-compilation-filter (f proc string) + (funcall f proc (xterm-color-filter string))) + +(advice-add 'compilation-filter :around #'sk/advice-compilation-filter) + +(defun sk/auto-recompile-buffer () + (interactive) + (if (member #'recompile after-save-hook) + (remove-hook 'after-save-hook #'recompile t) + (add-hook 'after-save-hook #'recompile nil t))) +#+end_src +** Project.el +#+begin_src emacs-lisp +(setq project-switch-commands '((project-find-file "Find file" "f") (project-find-dir "Find dir" "d") (project-dired "Dired" "D") (consult-ripgrep "ripgrep" "g") (magit-project-status "Magit" "m"))) +#+end_src +** Eglot (LSP) +#+begin_src emacs-lisp + (use-package eglot + :bind (:map eglot-mode-map + ("C-c C-a" . eglot-code-actions) + ("C-c C-r" . eglot-rename)) + :config + (setq eglot-autoshutdown t + eglot-confirm-server-initiated-edits nil)) + + ;; this'll make it so i don't have to use vscode every now and then + ;; (when (eq system-type 'windows-nt) + ;; (use-package eglot-booster + ;; :straight (eglot-booster :type git :host github :repo "jdtsmith/eglot-booster") + ;; :after eglot + ;; :config (eglot-booster-mode)) + ;; ) + + (when (eq system-type 'gnu/linux) + (use-package eglot-booster + :ensure nil + :config (eglot-booster-mode))) +#+end_src +** Magit +#+begin_src emacs-lisp +(use-package magit + :bind ("C-M-;" . magit-status-here) + :custom + (magit-show-long-lines-warning nil) + (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)) + +(use-package magit-todos + :after magit + :config + (magit-todos-mode)) + +;; -- magit forge -- +(use-package forge + :after magit) +(setq auth-sources '("~/.authinfo")) + +(defhydra sk/smerge-panel () + "smerge" + ("k" (smerge-prev) "prev change" ) + ("j" (smerge-next) "next change") + ("u" (smerge-keep-upper) "keep upper") + ("l" (smerge-keep-lower) "keep lower") + ("q" nil "quit" :exit t)) +#+end_src +** Formatting +#+begin_src emacs-lisp +(use-package apheleia + :hook (prog-mode . apheleia-mode)) +#+end_src +** Flycheck (Syntax Checking) +#+begin_src emacs-lisp +(use-package flycheck + :config + (global-flycheck-mode +1)) +#+end_src +** Treemacs +#+begin_src emacs-lisp +(use-package treemacs + :defer t + :init + (with-eval-after-load 'winum + (define-key winum-keymap (kbd "M-0") #'treemacs-select-window)) + :config + (progn + (setq treemacs-collapse-dirs (if treemacs-python-executable 3 0) + treemacs-deferred-git-apply-delay 0.5 + treemacs-directory-name-transformer #'identity + treemacs-display-in-side-window t + treemacs-eldoc-display 'simple + treemacs-file-event-delay 2000 + treemacs-file-extension-regex treemacs-last-period-regex-value + treemacs-file-follow-delay 0.2 + treemacs-file-name-transformer #'identity + treemacs-follow-after-init t + treemacs-expand-after-init t + treemacs-find-workspace-method 'find-for-file-or-pick-first + treemacs-git-command-pipe "" + treemacs-goto-tag-strategy 'refetch-index + treemacs-header-scroll-indicators '(nil . "^^^^^^") + treemacs-hide-dot-git-directory t + treemacs-indentation 2 + treemacs-indentation-string " " + treemacs-is-never-other-window nil + treemacs-max-git-entries 5000 + treemacs-missing-project-action 'ask + treemacs-move-forward-on-expand nil + treemacs-no-png-images nil + treemacs-no-delete-other-windows t + treemacs-project-follow-cleanup nil + treemacs-persist-file (expand-file-name ".cache/treemacs-persist" user-emacs-directory) + treemacs-position 'left + treemacs-read-string-input 'from-child-frame + treemacs-recenter-distance 0.1 + treemacs-recenter-after-file-follow nil + treemacs-recenter-after-tag-follow nil + treemacs-recenter-after-project-jump 'always + treemacs-recenter-after-project-expand 'on-distance + treemacs-litter-directories '("/node_modules" "/.venv" "/.cask") + treemacs-project-follow-into-home nil + treemacs-show-cursor nil + treemacs-show-hidden-files t + treemacs-silent-filewatch nil + treemacs-silent-refresh nil + treemacs-sorting 'alphabetic-asc + treemacs-select-when-already-in-treemacs 'move-back + treemacs-space-between-root-nodes t + treemacs-tag-follow-cleanup t + treemacs-tag-follow-delay 1.5 + treemacs-text-scale nil + treemacs-user-mode-line-format nil + treemacs-user-header-line-format nil + treemacs-wide-toggle-width 70 + treemacs-width 35 + treemacs-width-increment 1 + treemacs-width-is-initially-locked t + treemacs-workspace-switch-cleanup nil) + + ;; The default width and height of the icons is 22 pixels. If you are + ;; using a Hi-DPI display, uncomment this to double the icon size. + ;;(treemacs-resize-icons 44) + + (treemacs-follow-mode t) + (treemacs-tag-follow-mode t) + (treemacs-project-follow-mode t) + (treemacs-filewatch-mode t) + (treemacs-fringe-indicator-mode 'always) + (when treemacs-python-executable + (treemacs-git-commit-diff-mode t)) + + (pcase (cons (not (null (executable-find "git"))) + (not (null treemacs-python-executable))) + (`(t . t) + (treemacs-git-mode 'deferred)) + (`(t . _) + (treemacs-git-mode 'simple))) + + (treemacs-hide-gitignored-files-mode nil)) + :bind + (:map global-map + ("M-0" . treemacs-select-window) + ("C-x t 1" . treemacs-delete-other-windows) + ("C-x t d" . treemacs-select-directory) + ("C-x t B" . treemacs-bookmark) + ("C-x t C-t" . treemacs-find-file) + ("C-x t M-t" . treemacs-find-tag))) + +(use-package treemacs-evil + :after (treemacs evil)) + +(use-package treemacs-magit + :after (treemacs magit)) + +(use-package treemacs-nerd-icons + :config + (treemacs-load-theme "nerd-icons")) +#+end_src +** Direnv +#+begin_src emacs-lisp + (when (eq system-type 'gnu/linux) + (use-package envrc + :hook (after-init . envrc-global-mode))) +#+end_src +** Color Picker +#+begin_src emacs-lisp + (use-package zenity-color-picker) +#+end_src +** editorconfig +people will probably get mad at me if i dont have this and i try to contribute +#+begin_src emacs-lisp +(use-package editorconfig + :config + (editorconfig-mode 1)) +#+end_src +** wakatime +the feds are watching +#+begin_src emacs-lisp + (use-package wakatime-mode + :config + (global-wakatime-mode)) +#+end_src +* Languages +#+begin_src emacs-lisp +(message "Reached languages") +#+end_src +** HTML/CSS +#+begin_src emacs-lisp +(use-package web-mode + :hook (web-mode . eglot-ensure) + :mode ("\\.html\\'" + "\\.css\\'")) +#+end_src +** Javascript +#+begin_src emacs-lisp +(use-package js2-mode +:mode ("\\.js\\'" + "\\.jsx\\'") +:hook (js2-mode . eglot-ensure) +:config +(setq web-mode-markup-indent-offset 2) ; HTML +(setq web-mode-css-indent-offset 2) ; CSS +(setq web-mode-code-indent-offset 2) ; JS/JSX/TS/TSX +(setq web-mode-content-types-alist '(("jsx" . "\\.js[x]?\\'")))) +#+end_src +** Typescript +#+begin_src emacs-lisp + + (add-to-list 'auto-mode-alist '(".*\\.ts" . typescript-ts-mode)) + (add-to-list 'auto-mode-alist '(".*\\.tsx" . tsx-ts-mode)) + + (add-hook 'typescript-ts-mode-hook 'eglot-ensure) + (add-hook 'tsx-ts-mode-hook 'eglot-ensure) + + (setq treesit-language-source-alist + '((typescript "https://github.com/tree-sitter/tree-sitter-typescript" "master" "typescript/src" nil nil) + (tsx "https://github.com/tree-sitter/tree-sitter-typescript" "master" "tsx/src" nil nil))) +#+end_src +** Astro +#+begin_src emacs-lisp + (define-derived-mode astro-mode web-mode "astro") + (setq auto-mode-alist + (append '((".*\\.astro\\'" . astro-mode)) + auto-mode-alist)) + + (add-to-list 'eglot-server-programs + '(astro-mode . ("astro-ls" "--stdio" + :initializationOptions + (:typescript (:tsdk "./node_modules/typescript/lib"))))) +#+end_src +** C/C++ +#+begin_src emacs-lisp +(add-hook 'c-mode-hook 'eglot-ensure) +(add-hook 'c++-mode-hook 'eglot-ensure) +#+end_src +** C# +#+begin_src emacs-lisp + (add-hook 'csharp-mode-hook 'eglot-ensure) + (when (eq system-type 'gnu/linux) + (add-to-list 'eglot-server-programs + `(csharp-mode . ("OmniSharp" "-lsp")))) + + (use-package csproj-mode + :mode ("\\.csproj\\'")) + + (use-package dotnet + :hook (dotnet-mode . csharp-mode)) +#+end_src +** CMake +#+begin_src emacs-lisp +(use-package cmake-mode + :mode "CMakeLists.txt" + :hook (cmake-mode . eglot-ensure)) +#+end_src +** Lua +#+begin_src emacs-lisp +(use-package lua-mode + :mode "\\.lua\\'" + :hook (lua-mode . eglot-ensure)) +#+end_src +** Python +#+begin_src emacs-lisp +(use-package python-mode + :mode "\\.py\\'" + :hook (python-mode . eglot-ensure)) + +(use-package elpy +:after python-mode + +:custom +(elpy-rpc-python-command "python3") + +:config +(elpy-enable)) + +(use-package poetry + :config + (poetry-tracking-mode 1)) +#+end_src +** Yaml +#+begin_src emacs-lisp + (use-package yaml-mode + :hook (yaml-mode. eglot-ensure) + :mode ("\\.yml\\'" + "\\.yaml\\'")) +#+end_src +** Nix +#+begin_src emacs-lisp +(use-package nix-mode + :hook (nix-mode . eglot-ensure) + :mode "\\.nix\\'") +#+end_src +** Dart +#+begin_src emacs-lisp +(use-package dart-mode + :hook (dart-mode . eglot-ensure) +:mode "\\.dart\\'" ) +#+end_src +** Markdown +#+begin_src emacs-lisp +(use-package markdown-mode + :hook (markdown-mode . visual-line-mode)) + +(use-package markdown-preview-mode) +#+end_src +** GDScript +#+begin_src emacs-lisp +(use-package gdscript-mode + :hook (gdscript-mode . eglot-ensure) + :mode "\\.gd\\'") +#+end_src +** Rust +#+begin_src emacs-lisp + (use-package rustic + :ensure t + :config + (setq rustic-format-on-save nil) + (setq rustic-lsp-client 'eglot) + :custom + (rustic-cargo-use-last-stored-arguments t)) +#+end_src +** Haskell +#+begin_src emacs-lisp + (use-package haskell-mode + :hook (haskell-mode . eglot-ensure) + :mode "\\.hs'") +#+end_src +** Go +#+begin_src emacs-lisp + (use-package go-mode + :mode "\\.go\\'" + :hook (go-mode . eglot-ensure)) +#+end_src +* Social +#+begin_src emacs-lisp +(message "Reached social") +#+end_src +** Elcord (Discord rich precense) +#+begin_src emacs-lisp + (use-package elcord + :init + (setq elcord-display-buffer-details nil) + (setq elcord-use-major-mode-as-main-icon t) + (setq elcord-quiet t) + :config + (elcord-mode)) +#+end_src +** Telegram +does NOT WORK ON WINDOWS +#+begin_src emacs-lisp +(unless (eq system-type 'windows-nt) + (use-package telega)) +#+end_src +** elfeed (rss) +Will configure later, (use elfeed protocol ok ty) +#+begin_src emacs-lisp + (use-package elfeed + :config + (setq elfeed-use-curl t) + (elfeed-set-timeout 36000) + ) + + (use-package elfeed-protocol + :config + ;; setup feeds + (setq elfeed-protocol-fever-update-unread-only nil) + (setq elfeed-protocol-fever-fetch-category-as-tag t) + (setq elfeed-protocol-feeds '(("fever+https://sako@rss.sako.box" + :api-url "https://rss.sako.box/fever/" + :password (password-store-get "SelfHosted/rss.sako.box/fever")))) + + ;; enable elfeed-protocol + (setq elfeed-protocol-enabled-protocols '(fever)) + (elfeed-protocol-enable)) +#+end_src +** IRC (erc) +#+begin_src emacs-lisp + (require 'erc) + + (setq erc-server "znc.sako.box") + (setq erc-port "7000") + (setq erc-prompt "(^w^)->") + + (defun sakomacs/erc-znc-detach-channel () + (when (erc-server-process-alive) + (let ((tgt (erc-default-target))) + (erc-server-send (format "DETACH %s" tgt) + nil tgt)))) + + (add-hook 'erc-kill-channel-hook (sakomacs/erc-znc-detach-channel)) + + (defun sakomacs/begin-irc () + (interactive) + (erc-tls :server "znc.sako.box" :port "7000" :nick "sako" :password (concat "sako@emacs/Libera:" (password-store-get "SelfHosted/ZNC")))) + + ;; (advice-add 'irc :override + ;; (sakomacs/begin-irc)) +#+end_src +** Matrix +Ill set this up later as well +#+begin_src emacs-lisp + (use-package ement + :commands ement-connect + :custom + (ement-notify-dbus-p nil) ;; Turn off notifications + (ement-sessions-file "~/.cache/ement.el") + (ement-room-list-default-keys + '(;; Group all invitations (this group will appear first since the rooms are + ;; already sorted first). + ((membership :status 'invite)) + + ;; Group all left rooms (this group will appear last, because the rooms are already + ;; sorted last). + ((membership :status 'leave)) + + ;; Group all favorite rooms, which are already sorted first. + (favourite) + + ;; Group all low-priority rooms, which are already sorted last. + (low-priority) + + ;; Group other rooms which are unread. + (unread) + (people) + freshness))) +#+end_src +** Subsonic +#+begin_src emacs-lisp +(use-package subsonic) +#+end_src +** EMMS +Emacs music player lmfao +#+begin_src emacs-lisp + (use-package emms + :config + (emms-all) + (setq emms-player-list '(emms-player-mpd)) + (setq emms-info-functions '(emms-info-mod)) + (setq emms-source-file-default-directory "~/music") + ;; TODO Keybinds maybe + ) +#+end_src +** GPTel +its over the machines took over guys can i get my likes now +#+begin_src emacs-lisp + (use-package gptel + :config + (gptel-make-ollama "Ollama" + :host "localhost:11434" + :stream t + :models '("mistral:latest"))) +#+end_src +** mu4e +GNU patch review metho dor sometihng idk +#+begin_src emacs-lisp + + (use-package auth-source-xoauth2) + (use-package mu4e + :config + + ;; mu4e syncing issue with isync + (setq mu4e-change-filenames-when-moving t) + + ;; sending mail + ;;(setq message-send-mail-function 'smtpmail-send-it) + ;;(add-to-list 'smtpmail-auth-supported 'xoauth2) + (setq send-mail-function 'sendmail-send-it) + (setq message-send-mail-function 'sendmail-sent-it) + (setq sendmail-program (executable-find "msmtp")) + + ;; select the right sender email from the context. + (setq message-sendmail-envelope-from 'header) + + (setq mu4e-update-interval (* 10 60)) + (setq mu4e-get-mail-command (format "INSIDE_EMACS=%s offlineimap" emacs-version) + epa-pinentry-mode 'ask) + (setq mu4e-maildir "~/.mail") + + ;; for mail accounts + (setq sakomacs-mail-accounts (json-read-file "~/.mail/accounts.json")) + + (defun sakomacs/set-msmtp-account () + (if (message-mail-p) + (save-excursion + (let* + ((from (save-restriction + (message-narrow-to-headers) + (message-fetch-field "from"))) + (account + (cond + ((string-match (cdr (assoc 'gmail-1 sakomacs-mail-accounts)) from) "gmail-1") + ((string-match (cdr (assoc 'gmail-2 sakomacs-mail-accounts)) from) "gmail-2") + ((string-match (cdr (assoc 'protonmail sakomacs-mail-accounts)) from) "protonmail") + ((string-match (cdr (assoc 'li sakomacs-mail-accounts)) from) "li") + ((string-match (cdr (assoc 'outlook sakomacs-mail-accounts)) from))))) + (setq message-sendmail-extra-arguments (list '"-a" account)))))) + + (add-hook 'message-send-mail-hook 'sakomacs/set-msmtp-account) + + ;; kill message buffers + (setq message-kill-buffer-on-exit t) + + (setq mu4e-context-policy 'pick-first) + (setq mu4e-compose-context-policy 'always-ask) + (setq mu4e-contexts + (list + ;; outlook + (make-mu4e-context + :name "Outlook" + :match-func + (lambda (msg) + (when msg + (string-prefix-p "/outlook" (mu4e-message-field msg :maildir)))) + :vars `((user-mail-address . ,(cdr (assoc 'outlook sakomacs-mail-accounts))) + (user-full-name . "Sako") + (mu4e-drafts-folder . "/outlook/Drafts") + (mu4e-sent-folder . "/outlook/Sent") + (mu4e-refile-folder . "/outlook/Inbox") + (mu4e-trash-folder . "/outlook/Deleted") + ;; todo stmpmail and compose signatures + )) + (make-mu4e-context + :name "Proton" + :match-func + (lambda (msg) + (when msg + (string-prefix-p "/protonmail" (mu4e-message-field msg :maildir)))) + :vars `((user-mail-address . ,(cdr (assoc 'protonmail sakomacs-mail-accounts))) + (user-full-name . "Sako") + (mu4e-drafts-folder . "/protonmail/Drafts") + (mu4e-sent-folder . "/protonmail/Sent") + (mu4e-refile-folder . "/protonmail/Inbox") + (mu4e-trash-folder . "/protonmail/Trash")) + ;; todo stmpmail and compose signatures + ) + (make-mu4e-context + :name "Gmail Personal 1" + :match-func + (lambda (msg) + (when msg + (string-prefix-p "/gmail1" (mu4e-message-field msg :maildir)))) + :vars `((user-mail-address . ,(cdr (assoc 'gmail-1 sakomacs-mail-accounts))) + (user-full-name . "Sako") + (mu4e-drafts-folder . "/gmail1/Drafts") + (mu4e-sent-folder . "/gmail1/Sent Mail") + (mu4e-refile-folder . "/gmail1/Inbox") + (mu4e-trash-folder . "gmail1/Trash") + ;; todo stmpmail and compose signatures + )) + (make-mu4e-context + :name "Second Personal Gmail" + :match-func + (lambda (msg) + (when msg + (string-prefix-p "/gmail2" (mu4e-message-field msg :maildir)))) + :vars `((user-mail-address . ,(cdr (assoc 'gmail-2 sakomacs-mail-accounts))) + (user-full-name . "Sako") + (mu4e-drafts-folder . "/gmail2/Drafts") + (mu4e-sent-folder . "/gmail2/Sent Mail") + (mu4e-refile-folder . "/gmail2/Inbox") + (mu4e-trash-folder . "gmail2/Trash") + )) + (make-mu4e-context + :name "li" + :match-func + (lambda (msg) + (when msg + (string-prefix-p "/li" (mu4e-message-field msg :maildir)))) + :vars `((user-mail-address . ,(cdr (assoc 'li sakomacs-mail-accounts))) + (user-full-name . "user") + (mu4e-sent-folder . "/li/Sent Mail") + (mu4e-refile-folder . "/li/INBOX") + (mu4e-trash-folder . "/li/Trash") + )) + + )) + ) + + (use-package mu4e-alert + :after mu4e + :config + (setq mu4e-alert-notify-repeated-mails nil) + (mu4e-alert-enable-notifications)) +#+end_src +* Org +#+begin_src emacs-lisp +(message "Reached Org") +#+end_src +** Org mode configuration +#+begin_src emacs-lisp + (use-package org + :hook (org-mode . org-indent-mode) + :config + (setq org-ellipsis " ↓") + (setq org-agenda-start-with-log-mode t) + (setq org-log-done 'time) + (setq org-log-into-drawer t) + + ;; habits, useless for now though + ;; (require 'org-habit) + ;; (add-to-list 'org-modules 'org-habit) + ;; (setq org-habit-graph-column 60) + + ;; archive + (setq org-refile-targets + '(("archive.org" :maxlevel . 1))) + + ;; make sure to save everything after refiling + (advice-add 'org-refile :after 'org-save-all-org-buffers) + + ;; org agenda + (setq org-agenda-files + '("~/org/tasks.org" + "~/org/school.org" + "~/org/daily.org" + "~/org/irl.org" + "~/org/work.org")) + + ;; follow links + (setq org-return-follows-link t) + + ;; hide leading stars + (setq org-hide-leading-stars t) + (setq org-hide-emphasis-markers nil) + + ;; org latex pdf options + (setq org-latex-compiler "lualatex") + (setq org-preview-latex-default-process 'dvisvgm) + + ;; templates + (require 'org-tempo) + + ;; this'll come in handly later + (add-to-list 'org-structure-template-alist '("sh" . "src shell")) + (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp")) + (add-to-list 'org-structure-template-alist '("py" . "src python")) + + ;; more options + (setq org-todo-keywords + '((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d!)") + (sequence "BACKLOG(b)" "PLAN(p)" "READY(r)" "ACTIVE(a)" "REVIEW(v)" "WAIT(w@/!)" "HOLD(h)" "|" "COMPLETED(c)" "CANCELED(k@)"))) + + ;; this is really useful + (setq org-startup-with-inline-images t) + + ;; i hope i actually use this eventually + (setq org-capture-templates + `(("t" "Tasks") + ("tt" "Task" entry (file+olp "~/org/tasks.org" "captured") + "* TODO %?\n %U\n %a\n %i" :empty-lines1))) + ) + + +#+end_src +** Org Roam +#+begin_src emacs-lisp + (use-package org-roam + :custom + (org-roam-directory "~/org/notes") + :bind (("C-c n l" . org-roam-buffer-toggle) + ("C-c n f" . org-roam-node-find) + ("C-c n i" . org-roam-node-insert)) + :config + (org-roam-setup)) +#+end_src +** Org-wild-notifier +#+begin_src emacs-lisp + (use-package org-wild-notifier + :config + (setq alert-default-style 'libnotify) + (setq org-wild-notifier-alert-time 30) + (org-wild-notifier-mode)) +#+end_src +** Org-Pomodoro +#+begin_src emacs-lisp +(use-package org-pomodoro) +#+end_src +** PDF-Tools +Export and then view with emacs :) +#+begin_src emacs-lisp +(use-package pdf-tools) +#+end_src +* EXWM +I'm scared +#+begin_src emacs-lisp + + (defcustom is-exwm nil + "Toggle if EXWM is being used" + :type 'boolean) + + (when (eq system-type 'gnu/linux) + (when is-exwm + (use-package exwm + :config + (set-frame-parameter nil 'alpha '(90 . 90)) + (add-to-list 'default-frame-alist '(alpha . (90 . 90))) + + (defun sakomacs/exwm-init-hook () + ;; background + (call-process-shell-command "feh --bg-fill ~/background.png" nil 0) + ;; (set-frame-parameter nil 'alpha 90) + ;; (call-process-shell-command "~/.config/polybar/startpolybar" nil 0) + (call-process-shell-command "~/.config/picom/startpicom" nil 0) + ;; startup + (call-process-shell-command "nm-applet" nil 0) + (call-process-shell-command "blueman-applet" nil 0) + ;; (call-process-shell-command "nextcloud" nil 0) + ;; (call-process-shell-command "bitwarden" nil 0) + (call-process-shell-command "flameshot" nil 0) + + ;; battery + (display-battery-mode) + ;; show time on the modeline + (setq display-time-default-load-average nil) + (setq display-time-24hr-format t) + (display-time-mode t) + ;; shrink fringe to 1px + (fringe-mode 1) + ) + + ;; background + ;; todo turn this info a function + (add-hook 'exwm-init-hook 'sakomacs/exwm-init-hook) + ;; startup + ;; workspaces + (setq exwm-workspace-number 5) + + + (require 'exwm-systemtray) + (exwm-systemtray-enable) + + ;; polybar + (defvar sakomacs/polybar-process nil + "Holds the process of the running Polybar instance, if any") + + (server-start) + + (defun sakomacs/kill-panel () + (interactive) + (when sakomacs/polybar-process + (ignore-errors + (kill-process sakomacs/polybar-process))) + (setq sakomacs/polybar-process nil)) + + (defun sakomacs/start-panel () + (interactive) + (sakomacs/kill-panel) + (setq sakomacs/polybar-process (start-process-shell-command "polybar" nil "polybar panel"))) + + (defun sakomacs/send-polybar-hook (module-name hook-index) + (start-process-shell-command "polybar-msg" nil (format "polybar-msg hook %s %s" module-name hook-index))) + + (defun sakomacs/send-polybar-exwm-workspace () + (sakomacs/send-polybar-hook "exwm-workspace" 1)) + + ;; Update panel indicator when workspace changes + (add-hook 'exwm-workspace-switch-hook #'sakomacs/send-polybar-exwm-workspace) + + + ;; make the buffer names better + (add-hook 'exwm-update-class-hook + (lambda () + (unless (or (string-prefix-p "sun-awt-X11-" exwm-instance-name) + (string= "gimp" exwm-instance-name)) + (exwm-workspace-rename-buffer exwm-class-name)))) + (add-hook 'exwm-update-title-hook + (lambda () + (when (or (not exwm-instance-name) + (string-prefix-p "sun-awt-X11-" exwm-instance-name) + (string= "gimp" exwm-instance-name)) + (exwm-workspace-rename-buffer exwm-title)))) + + ;; always use these keys in emacs + (setq exwm-input-prefix-keys + '(?\C-x + ?\C-u + ?\C-h + ?\M-x + ?\M-` + ?\M-& + ?\M-: + ?\C-\M-j ;; Buffer list + ?\C-\ )) ;; Ctrl+Space + + (setq exwm-input-stimulation-keys + '( + ;; cut/paste. + ([?\C-w] . [?\C-x]) + ([?\M-w] . [?\C-c]) + ([?\C-y] . [?\C-v]))) + + + ;; Ctrl+/3Q will enable the next key to be sent directly + (define-key exwm-mode-map [?\C-q] 'exwm-input-send-next-key) + ;; app launcher and fullscreen + (exwm-input-set-key (kbd "s-SPC") 'app-launcher-run-app) + (exwm-input-set-key (kbd "s-f") 'exwm-layout-toggle-fullscreen) + (exwm-input-set-key (kbd "s-") 'vterm) + + ;; kill apps + (exwm-input-set-key (kbd "s-q") #'kill-current-buffer) + + ;; Set up global key bindings. These always work, no matter the input state! + ;; Keep in mind that changing this list after EXWM initializes has no effect. + (setq exwm-input-global-keys + `( + ;; Reset to line-mode (C-c C-k switches to char-mode via exwm-input-release-keyboard) + ([?\s-r] . exwm-reset) + + ;; Move between windows + ([s-left] . windmove-left) + ([s-right] . windmove-right) + ([s-up] . windmove-up) + ([s-down] . windmove-down) + + ;; Launch applications via shell command + ([?\s-&] . (lambda (command) + (interactive (list (read-shell-command "$ "))) + (start-process-shell-command command nil command))) + + ;; Switch workspace + ([?\s-w] . exwm-workspace-switch) + + ;; 's-N': Switch to certain workspace with Super (Win) plus a number key (0 - 9) + ,@(mapcar (lambda (i) + `(,(kbd (format "s-%d" i)) . + (lambda () + (interactive) + (exwm-workspace-switch-create ,i)))) + (number-sequence 0 9)))) + ) + + (use-package desktop-environment + :after exwm + :config (desktop-environment-mode) + :custom + (desktop-environment-brightness-small-increment "2%+") + (desktop-environment-brightness-small-decrement "2%-") + (desktop-environment-brightness-normal-increment "5%+") + (desktop-environment-brightness-normal-decrement "5%-")) + )) +#+end_src +* End +#+begin_src elisp + (message "Welcome to Emacs!") + + ;; EOF +#+end_src diff --git a/config/foot/foot.ini b/config/foot/foot.ini deleted file mode 100644 index 2f99cd2a..00000000 --- a/config/foot/foot.ini +++ /dev/null @@ -1,236 +0,0 @@ -# -*- conf -*- - -# shell=$SHELL (if set, otherwise user's default shell from /etc/passwd) -term=xterm-256color -# login-shell=no - -# app-id=foot # globally set wayland app-id. Default values are "foot" and "footclient" for desktop and server mode -# title=foot -# locked-title=no - -font=JetBrainsMono NF:size=12 -# font-bold= -# font-italic= -# font-bold-italic= -# font-size-adjustment=0.5 -# line-height= -# letter-spacing=0 -# horizontal-letter-offset=0 -# vertical-letter-offset=0 -# underline-offset= -# underline-thickness= -# box-drawings-uses-font-glyphs=no -# dpi-aware=no - -# initial-window-size-pixels=700x500 # Or, -# initial-window-size-chars= -# initial-window-mode=windowed -# pad=0x0 # optionally append 'center' -# resize-by-cells=yes -# resize-delay-ms=100 - -# bold-text-in-bright=no -# word-delimiters=,│`|:"'()[]{}<> -# selection-target=primary -# workers= -# utmp-helper=/usr/lib/utempter/utempter # When utmp backend is ‘libutempter’ (Linux) -# utmp-helper=/usr/libexec/ulog-helper # When utmp backend is ‘ulog’ (FreeBSD) - -[environment] -# name=value - -[bell] -# urgent=no -# notify=no -# visual=no -# command= -# command-focused=no - -#[desktop-notifications] -# command=notify-send --wait --app-name ${app-id} --icon ${app-id} --category ${category} --urgency ${urgency} --expire-time ${expire-time} --hint STRING:image-path:${icon} --replace-id ${replace-id} ${action-argument} --print-id -- ${title} ${body} -# command-action-argument=--action ${action-name}=${action-label} -# close="" -# inhibit-when-focused=yes - - -[scrollback] -lines=1000 -# multiplier=3.0 -# indicator-position=relative -# indicator-format="" - -[url] -# launch=xdg-open ${url} -# label-letters=sadfjklewcmpgh -# osc8-underline=url-mode -# protocols=http, https, ftp, ftps, file, gemini, gopher -# uri-characters=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.,~:;/?#@!$&%*+="'()[] - -[cursor] -# style=block -# color= -# blink=no -# blink-rate=500 -# beam-thickness=1.5 -# underline-thickness= - -[mouse] -# hide-when-typing=no -# alternate-scroll-mode=yes - -[touch] -# long-press-delay=400 - -[colors] -# alpha=1.0 -# background=242424 -# foreground=ffffff -# flash=7f7f00 -# flash-alpha=0.5 - -## Normal/regular colors (color palette 0-7) -# regular0=242424 # black -# regular1=f62b5a # red -# regular2=47b413 # green -# regular3=e3c401 # yellow -# regular4=24acd4 # blue -# regular5=f2affd # magenta -# regular6=13c299 # cyan -# regular7=e6e6e6 # white - -## Bright colors (color palette 8-15) -# bright0=616161 # bright black -# bright1=ff4d51 # bright red -# bright2=35d450 # bright green -# bright3=e9e836 # bright yellow -# bright4=5dc5f8 # bright blue -# bright5=feabf2 # bright magenta -# bright6=24dfc4 # bright cyan -# bright7=ffffff # bright white - -## dimmed colors (see foot.ini(5) man page) -# dim0= -# ... -# dim7= - -## The remaining 256-color palette -# 16 = <256-color palette #16> -# ... -# 255 = <256-color palette #255> - -## Misc colors -# selection-foreground= -# selection-background= -# jump-labels= # black-on-yellow -# scrollback-indicator= # black-on-bright-blue -# search-box-no-match= # black-on-red -# search-box-match= # black-on-yellow -# urls= - -[csd] -# preferred=server -# size=26 -# font= -# color= -# hide-when-maximized=no -# double-click-to-maximize=yes -# border-width=0 -# border-color= -# button-width=26 -# button-color= -# button-minimize-color= -# button-maximize-color= -# button-close-color= - -[key-bindings] -# scrollback-up-page=Shift+Page_Up -# scrollback-up-half-page=none -# scrollback-up-line=none -# scrollback-down-page=Shift+Page_Down -# scrollback-down-half-page=none -# scrollback-down-line=none -# scrollback-home=none -# scrollback-end=none -# clipboard-copy=Control+Shift+c XF86Copy -# clipboard-paste=Control+Shift+v XF86Paste -# primary-paste=Shift+Insert -# search-start=Control+Shift+r -# font-increase=Control+plus Control+equal Control+KP_Add -# font-decrease=Control+minus Control+KP_Subtract -# font-reset=Control+0 Control+KP_0 -# spawn-terminal=Control+Shift+n -# minimize=none -# maximize=none -# fullscreen=none -# pipe-visible=[sh -c "xurls | fuzzel | xargs -r firefox"] none -# pipe-scrollback=[sh -c "xurls | fuzzel | xargs -r firefox"] none -# pipe-selected=[xargs -r firefox] none -# pipe-command-output=[wl-copy] none # Copy last command's output to the clipboard -# show-urls-launch=Control+Shift+o -# show-urls-copy=none -# show-urls-persistent=none -# prompt-prev=Control+Shift+z -# prompt-next=Control+Shift+x -# unicode-input=Control+Shift+u -# noop=none - -[search-bindings] -# cancel=Control+g Control+c Escape -# commit=Return -# find-prev=Control+r -# find-next=Control+s -# cursor-left=Left Control+b -# cursor-left-word=Control+Left Mod1+b -# cursor-right=Right Control+f -# cursor-right-word=Control+Right Mod1+f -# cursor-home=Home Control+a -# cursor-end=End Control+e -# delete-prev=BackSpace -# delete-prev-word=Mod1+BackSpace Control+BackSpace -# delete-next=Delete -# delete-next-word=Mod1+d Control+Delete -# extend-char=Shift+Right -# extend-to-word-boundary=Control+w Control+Shift+Right -# extend-to-next-whitespace=Control+Shift+w -# extend-line-down=Shift+Down -# extend-backward-char=Shift+Left -# extend-backward-to-word-boundary=Control+Shift+Left -# extend-backward-to-next-whitespace=none -# extend-line-up=Shift+Up -# clipboard-paste=Control+v Control+Shift+v Control+y XF86Paste -# primary-paste=Shift+Insert -# unicode-input=none -# quit=none -# scrollback-up-page=Shift+Page_Up -# scrollback-up-half-page=none -# scrollback-up-line=none -# scrollback-down-page=Shift+Page_Down -# scrollback-down-half-page=none -# scrollback-down-line=none -# scrollback-home=none -# scrollback-end=none - -[url-bindings] -# cancel=Control+g Control+c Control+d Escape -# toggle-url-visible=t - -[text-bindings] -# \x03=Mod4+c # Map Super+c -> Ctrl+c - -[mouse-bindings] -# scrollback-up-mouse=BTN_WHEEL_BACK -# scrollback-down-mouse=BTN_WHEEL_FORWARD -# font-increase=Control+BTN_WHEEL_BACK -# font-decrease=Control+BTN_WHEEL_FORWARD -# selection-override-modifiers=Shift -# primary-paste=BTN_MIDDLE -# select-begin=BTN_LEFT -# select-begin-block=Control+BTN_LEFT -# select-extend=BTN_RIGHT -# select-extend-character-wise=Control+BTN_RIGHT -# select-word=BTN_LEFT-2 -# select-word-whitespace=Control+BTN_LEFT-2 -# select-quote = BTN_LEFT-3 -# select-row=BTN_LEFT-4 - -# vim: ft=dosini diff --git a/config/hyprland/hyprland.conf b/config/hyprland/hyprland.conf index 092e9773..e1116fd6 100644 --- a/config/hyprland/hyprland.conf +++ b/config/hyprland/hyprland.conf @@ -56,9 +56,11 @@ input { kb_layout = us, ara kb_variant = kb_model = - kb_options = grp:alt_shift_toggle, ctrl:nocaps + kb_options = grp:ctrls_toggle, ctrl:nocaps kb_rules = + numlock_by_default = true + # no mouse acceleration pls :) accel_profile = flat @@ -75,11 +77,11 @@ input { general { # See https://wiki.hyprland.org/Configuring/Variables/ for more - gaps_in = 10 - gaps_out = 10 - border_size = 1 - col.active_border = rgba(33ccffee) rgba(00ff99ee) 45deg - col.inactive_border = rgba(595959aa) + gaps_in = 10 + gaps_out = 10 + border_size = 2 + col.active_border = rgba(ea4c88ee) rgba(e691b1ee) 45deg + col.inactive_border = rgb(6F2440) rgb(734959) 45deg layout = dwindle } @@ -105,7 +107,7 @@ decoration { } animations { - enabled = false + enabled = false # Some default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more diff --git a/config/hyprland/hyprlock.conf b/config/hyprland/hyprlock.conf index cd41f39f..d4ecf717 100644 --- a/config/hyprland/hyprlock.conf +++ b/config/hyprland/hyprlock.conf @@ -3,18 +3,38 @@ background { path = /home/sako/background.png } +general { + no_fade_in = true + no_fade_out = true +} + +# Time +label { + monitor = + text = $TIME + text_align = center # center/right or any value for default left. multi-line text alignment inside label container + color = rgba(200, 200, 200, 1.0) + font_size = 25 + font_family = JetBrains Mono + rotate = 0 # degrees, counter-clockwise + + position = 0, 80 + halign = center + valign = center +} + input-field { monitor = size = 300, 50 - outline_thickness = 4 + outline_thickness = 1 dots_size = 0.1 dots_spacing = 0.2 dots_center = true - outer_color = $accent + outer_color =rgb(ea4c88) inner_color = $surface0 font_color = $text fade_on_empty = false - placeholder_text = silly! + placeholder_text = placeholder rounding = 0 hide_input = false check_color = $accent diff --git a/config/nvim/init.lua b/config/nvim/init.lua index 819f7ab2..15efce21 100644 --- a/config/nvim/init.lua +++ b/config/nvim/init.lua @@ -1,3 +1,3 @@ require("core.keymaps") require("core.plugins") -require("core.plugin_config") +-- require("core.plugin_config") diff --git a/config/nvim/lua/core/plugins.lua b/config/nvim/lua/core/plugins.lua index 97849178..035425f3 100644 --- a/config/nvim/lua/core/plugins.lua +++ b/config/nvim/lua/core/plugins.lua @@ -15,121 +15,11 @@ vim.opt.rtp:prepend(lazypath) vim.g.mapleader = " " local plugins = { - - -- whats an ide without a file explorer - "nvim-tree/nvim-tree.lua", - "nvim-tree/nvim-web-devicons", - - -- colorscheme - -- { "bluz71/vim-moonfly-colors", name = "moonfly", lazy = false, priority = 1000 }, - "savq/melange-nvim", - - -- default bar only looks good on linux - "nvim-lualine/lualine.nvim", - -- syntax highlighting apparently "nvim-treesitter/nvim-treesitter", "windwp/nvim-ts-autotag", - -- org mode -{ - 'nvim-orgmode/orgmode', - event = 'VeryLazy', - config = function() - -- Setup orgmode - require('orgmode').setup({ - org_agenda_files = '~/orgfiles/**/*', - org_default_notes_file = '~/orgfiles/refile.org', - }) - - -- NOTE: If you are using nvim-treesitter with `ensure_installed = "all"` option - -- add `org` to ignore_install - -- require('nvim-treesitter.configs').setup({ - -- ensure_installed = 'all', - -- ignore_install = { 'org' }, - -- }) - end, -}, - - -- like fzf but goofier - { - "nvim-telescope/telescope.nvim", - version = "0.1.1", - dependencies = { { "nvim-lua/plenary.nvim" } }, - }, - -- lsp stuff - { - "williamboman/mason.nvim", - "williamboman/mason-lspconfig.nvim", - "neovim/nvim-lspconfig", - }, - - -- completion - "hrsh7th/nvim-cmp", - "hrsh7th/cmp-buffer", - "hrsh7th/cmp-path", - "hrsh7th/cmp-nvim-lsp", - "onsails/lspkind.nvim", - - -- snippet - "L3MON4D3/LuaSnip", - "saadparwaiz1/cmp_luasnip", - - -- auto close to prevent carpal tunnel : - "windwp/nvim-autopairs", - - -- git stuff lol - "lewis6991/gitsigns.nvim", - - -- flex - "andweeb/presence.nvim", - - -- color picker - "ziontee113/color-picker.nvim", - - -- startup - { - "glepnir/dashboard-nvim", - config = function() - require("dashboard").setup({ - theme = "doom", -- theme is doom and hyper default is hyper - config = { - -- todo https://github.com/nvimdev/dashboard-nvim - center = { - { - icon = " ", - icon_hl = "Title", - desc = "Find File ", - desc_hl = "String", - keymap = "SPC SPC", - key_hl = "Number", - action = "lua print(2)", - }, - }, - }, - }) - end, - event = "VimEnter", - dependencies = { { "nvim-tree/nvim-web-devicons" } }, - }, - - -- floating terminal, useful to mimic/be better than vscode - "voldikss/vim-floaterm", - - -- git client - { - "NeogitOrg/neogit", - dependencies = { - "nvim-lua/plenary.nvim", -- required - "sindrets/diffview.nvim", -- optional - Diff integration - - -- Only one of these is needed, not both. - "nvim-telescope/telescope.nvim", -- optional - "ibhagwan/fzf-lua", -- optional - }, - config = true - }, - + { "wakatime/vim-wakatime", lazy = false }, } require("lazy").setup(plugins, {}) diff --git a/config/qtile/config.py b/config/qtile/config.py deleted file mode 100644 index b1463fd4..00000000 --- a/config/qtile/config.py +++ /dev/null @@ -1,213 +0,0 @@ -# Copyright (c) 2010 Aldo Cortesi -# Copyright (c) 2010, 2014 dequis -# Copyright (c) 2012 Randall Ma -# Copyright (c) 2012-2014 Tycho Andersen -# Copyright (c) 2012 Craig Barnes -# Copyright (c) 2013 horsik -# Copyright (c) 2013 Tao Sauvage -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -from libqtile import bar, layout, widget -from libqtile.config import Click, Drag, Group, Key, Match, Screen -from libqtile.lazy import lazy -from libqtile.utils import guess_terminal - -mod = "mod4" -terminal = "kitty" - -keys = [ - # A list of available commands that can be bound to keys can be found - # at https://docs.qtile.org/en/latest/manual/config/lazy.html - # Switch between windows - Key([mod], "h", lazy.layout.left(), desc="Move focus to left"), - Key([mod], "l", lazy.layout.right(), desc="Move focus to right"), - Key([mod], "j", lazy.layout.down(), desc="Move focus down"), - Key([mod], "k", lazy.layout.up(), desc="Move focus up"), - Key([mod], "space", lazy.layout.next(), desc="Move window focus to other window"), - # Move windows between left/right columns or move up/down in current stack. - # Moving out of range in Columns layout will create new column. - Key( - [mod, "shift"], "h", lazy.layout.shuffle_left(), desc="Move window to the left" - ), - Key( - [mod, "shift"], - "l", - lazy.layout.shuffle_right(), - desc="Move window to the right", - ), - Key([mod, "shift"], "j", lazy.layout.shuffle_down(), desc="Move window down"), - Key([mod, "shift"], "k", lazy.layout.shuffle_up(), desc="Move window up"), - # Grow windows. If current window is on the edge of screen and direction - # will be to screen edge - window would shrink. - Key([mod, "control"], "h", lazy.layout.grow_left(), desc="Grow window to the left"), - Key( - [mod, "control"], "l", lazy.layout.grow_right(), desc="Grow window to the right" - ), - Key([mod, "control"], "j", lazy.layout.grow_down(), desc="Grow window down"), - Key([mod, "control"], "k", lazy.layout.grow_up(), desc="Grow window up"), - Key([mod], "n", lazy.layout.normalize(), desc="Reset all window sizes"), - # Toggle between split and unsplit sides of stack. - # Split = all windows displayed - # Unsplit = 1 window displayed, like Max layout, but still with - # multiple stack panes - Key( - [mod, "shift"], - "Return", - lazy.layout.toggle_split(), - desc="Toggle between split and unsplit sides of stack", - ), - Key([mod], "Return", lazy.spawn(terminal), desc="Launch terminal"), - # Toggle between different layouts as defined below - Key([mod], "Tab", lazy.next_layout(), desc="Toggle between layouts"), - Key([mod], "w", lazy.window.kill(), desc="Kill focused window"), - Key([mod, "control"], "r", lazy.reload_config(), desc="Reload the config"), - Key([mod, "control"], "q", lazy.shutdown(), desc="Shutdown Qtile"), - Key([mod], "r", lazy.spawncmd(), desc="Spawn a command using a prompt widget"), -] - -groups = [Group(i) for i in "123456789"] - -for i in groups: - keys.extend( - [ - # mod1 + letter of group = switch to group - Key( - [mod], - i.name, - lazy.group[i.name].toscreen(), - desc="Switch to group {}".format(i.name), - ), - # mod1 + shift + letter of group = switch to & move focused window to group - Key( - [mod, "shift"], - i.name, - lazy.window.togroup(i.name, switch_group=True), - desc="Switch to & move focused window to group {}".format(i.name), - ), - # Or, use below if you prefer not to switch to that group. - # # mod1 + shift + letter of group = move focused window to group - # Key([mod, "shift"], i.name, lazy.window.togroup(i.name), - # desc="move focused window to group {}".format(i.name)), - ] - ) - -layouts = [ - layout.Columns(border_focus_stack=["#d75f5f", "#8f3d3d"], border_width=4), - layout.Max(), - # Try more layouts by unleashing below layouts. - # layout.Stack(num_stacks=2), - # layout.Bsp(), - # layout.Matrix(), - # layout.MonadTall(), - # layout.MonadWide(), - # layout.RatioTile(), - # layout.Tile(), - # layout.TreeTab(), - # layout.VerticalTile(), - # layout.Zoomy(), -] - -widget_defaults = dict( - font="sans", - fontsize=12, - padding=3, -) -extension_defaults = widget_defaults.copy() - -screens = [ - Screen( - bottom=bar.Bar( - [ - widget.CurrentLayout(), - widget.GroupBox(), - widget.Prompt(), - widget.WindowName(), - widget.Chord( - chords_colors={ - "launch": ("#ff0000", "#ffffff"), - }, - name_transform=lambda name: name.upper(), - ), - widget.TextBox("default config", name="default"), - widget.TextBox("Press <M-r> to spawn", foreground="#d75f5f"), - # NB Systray is incompatible with Wayland, consider using StatusNotifier instead - # widget.StatusNotifier(), - widget.Systray(), - widget.Clock(format="%Y-%m-%d %a %I:%M %p"), - widget.QuickExit(), - ], - 24, - # border_width=[2, 0, 2, 0], # Draw top and bottom borders - # border_color=["ff00ff", "000000", "ff00ff", "000000"] # Borders are magenta - ), - ), -] - -# Drag floating layouts. -mouse = [ - Drag( - [mod], - "Button1", - lazy.window.set_position_floating(), - start=lazy.window.get_position(), - ), - Drag( - [mod], "Button3", lazy.window.set_size_floating(), start=lazy.window.get_size() - ), - Click([mod], "Button2", lazy.window.bring_to_front()), -] - -dgroups_key_binder = None -dgroups_app_rules = [] # type: list -follow_mouse_focus = True -bring_front_click = False -cursor_warp = False -floating_layout = layout.Floating( - float_rules=[ - # Run the utility of `xprop` to see the wm class and name of an X client. - *layout.Floating.default_float_rules, - Match(wm_class="confirmreset"), # gitk - Match(wm_class="makebranch"), # gitk - Match(wm_class="maketag"), # gitk - Match(wm_class="ssh-askpass"), # ssh-askpass - Match(title="branchdialog"), # gitk - Match(title="pinentry"), # GPG key password entry - ] -) -auto_fullscreen = True -focus_on_window_activation = "smart" -reconfigure_screens = True - -# If things like steam games want to auto-minimize themselves when losing -# focus, should we respect this or not? -auto_minimize = True - -# When using the Wayland backend, this can be used to configure input devices. -wl_input_rules = None - -# XXX: Gasp! We're lying here. In fact, nobody really uses or cares about this -# string besides java UI toolkits; you can see several discussions on the -# mailing lists, GitHub issues, and other WM documentation that suggest setting -# this string if your java app doesn't work correctly. We may as well just lie -# and say that we're a working one by default. -# -# We choose LG3D to maximize irony: it is a 3D non-reparenting WM written in -# java that happens to be on java's whitelist. -wmname = "LG3D" diff --git a/default.nix b/default.nix index 2fd49b2f..b6d0acb5 100644 --- a/default.nix +++ b/default.nix @@ -1,20 +1,12 @@ -{ - config, - inputs, - outputs, - pkgs, - lib, - home-manager, - ... -}: { +{ config, inputs, outputs, pkgs, lib, home-manager, ... }: { imports = [ # home manager inputs.home-manager.nixosModules.default - # modules + inputs.agenix.nixosModules.default + # TODO:: GET RID OF THIS PLEASE + # my modules modules # import for each folder - # modules/desktop IMPORT - # modules/desktop/example DO NOT IMPORT, - # add entry to module's default.nix + # add entry to module category's default.nix outputs.nixosModules.desktop outputs.nixosModules.shell outputs.nixosModules.hardware @@ -28,7 +20,7 @@ # nix settings that should 100% be global #nix.settings.experimental-features = ["nix-command" "flakes"]; nix.settings = { - experimental-features = ["nix-command" "flakes"]; + experimental-features = [ "nix-command" "flakes" ]; substituters = [ # garnix "https://cache.garnix.io" @@ -67,7 +59,7 @@ efiSysMountPoint = "/boot/efi"; }; grub = { - devices = ["nodev"]; + devices = [ "nodev" ]; efiSupport = true; enable = true; useOSProber = true; @@ -99,13 +91,12 @@ users.users.sako = { isNormalUser = true; - extraGroups = ["wheel" "networkmanager"]; # Enable ‘sudo’ for the user. + extraGroups = [ "wheel" "networkmanager" "audio" ]; }; home-manager.useUserPackages = true; - home-manager.users.sako = {pkgs, ...}: { - # CHANGE THIS WHEN THE SYSTEM VERSION CHANGES TOO!!! - home.packages = []; + home-manager.users.sako = { pkgs, ... }: { + home.packages = [ ]; home.username = "sako"; home.homeDirectory = "/home/sako"; programs.bash.enable = true; @@ -118,11 +109,7 @@ enable = true; userName = "Sakooooo"; userEmail = "78461130+Sakooooo@users.noreply.github.com"; - includes = [ - { - path = "~/.config/git/config.local"; - } - ]; + includes = [{ path = "~/.config/git/config.local"; }]; extraConfig = { color.ui = "auto"; init.defaultBranch = "master"; @@ -134,18 +121,18 @@ # bare minimum environment.systemPackages = with pkgs; [ vim # backup - wget #double u get + wget # double u get killall # die processes - alsa-utils # unsupported application - pulseaudio # unsupported application - pamixer # unsupported application - feh # im different unzip # zip file gh # github htop # htop tree # trees ripgrep # better grep may help later + inputs.agenix.packages.${system}.default ]; + + age.secretsDir = "/run/secrets"; + # you phisiclally cannot live without this # litearlly! ! ! ! ! ! programs.gnupg.agent = { @@ -154,6 +141,8 @@ settings = { allow-emacs-pinentry = ""; allow-loopback-pinentry = ""; + default-cache-ttl = "28800"; + max-cache-ttl = "28800"; }; # enableSSHSupport = true; }; @@ -163,8 +152,4 @@ # package = pkgs.gitFull; # }; - # read stable version patch notes and fix any issues - # then you can change this - #system.stateVersion = "23.05"; - # read comment you read the comment? } diff --git a/flake.lock b/flake.lock index b644d5f5..6477ec8b 100644 --- a/flake.lock +++ b/flake.lock @@ -9,11 +9,11 @@ ] }, "locked": { - "lastModified": 1725358307, - "narHash": "sha256-su/Nzp2X8JlaD9wPYQGXeTilaVa5H06X7A3kqCLJNuo=", + "lastModified": 1728588346, + "narHash": "sha256-P1j+Nf+pzxPYK2Qe7lF2yB0vR3YvW8Td5sD0ZvrKIq8=", "owner": "nix-community", "repo": "NixOS-WSL", - "rev": "8a89995f745b1a9029d654c391a0f62ca03f7fe7", + "rev": "0fc8d9bb51cc46b31d950513df6d088905c8fe55", "type": "github" }, "original": { @@ -22,19 +22,42 @@ "type": "github" } }, - "ags": { + "agenix": { "inputs": { + "darwin": "darwin", + "home-manager": "home-manager", "nixpkgs": [ "nixpkgs" ], "systems": "systems_2" }, "locked": { - "lastModified": 1721306136, - "narHash": "sha256-VKPsIGf3/a+RONBipx4lEE4LXG2sdMNkWQu22LNQItg=", + "lastModified": 1723293904, + "narHash": "sha256-b+uqzj+Wa6xgMS9aNbX4I+sXeb5biPDi39VgvSFqFvU=", + "owner": "ryantm", + "repo": "agenix", + "rev": "f6291c5935fdc4e0bef208cfc0dcab7e3f7a1c41", + "type": "github" + }, + "original": { + "owner": "ryantm", + "repo": "agenix", + "type": "github" + } + }, + "ags": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems_3" + }, + "locked": { + "lastModified": 1728326430, + "narHash": "sha256-tV1ABHuA1HItMdCTuNdA8fMB+qw7LpjvI945VwMSABI=", "owner": "Aylur", "repo": "ags", - "rev": "344ea72cd3b8d4911f362fec34bce7d8fb37028c", + "rev": "60180a184cfb32b61a1d871c058b31a3b9b0743d", "type": "github" }, "original": { @@ -63,11 +86,11 @@ ] }, "locked": { - "lastModified": 1725199881, - "narHash": "sha256-jsmipf/u1GFZE5tBUkr56CHMN6VpUWCAjfLIhvQijU0=", + "lastModified": 1728326504, + "narHash": "sha256-dQXAj+4d6neY7ldCiH6gNym3upP49PVxRzEPxXlD9Aw=", "owner": "hyprwm", "repo": "aquamarine", - "rev": "f8a687dd29ff019657498f1bd14da2fbbf0e604b", + "rev": "65dd97b5d21e917295159bbef1d52e06963f4eb0", "type": "github" }, "original": { @@ -76,6 +99,28 @@ "type": "github" } }, + "darwin": { + "inputs": { + "nixpkgs": [ + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1700795494, + "narHash": "sha256-gzGLZSiOhf155FW7262kdHo2YDeugp3VuIFb4/GGng0=", + "owner": "lnl7", + "repo": "nix-darwin", + "rev": "4b9b83d5a92e8c1fbfd8eb27eda375908c11ec4d", + "type": "github" + }, + "original": { + "owner": "lnl7", + "ref": "master", + "repo": "nix-darwin", + "type": "github" + } + }, "emacs-overlay": { "inputs": { "flake-utils": "flake-utils_2", @@ -83,11 +128,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1725674458, - "narHash": "sha256-AeemHTjtU56bXUCXJ4CrEJmIOfXfALkIR8Ix+AVlclg=", + "lastModified": 1728753084, + "narHash": "sha256-OgpebVl9jecLspSckK9xeYk804z9GM2ROClCJbmPpac=", "owner": "nix-community", "repo": "emacs-overlay", - "rev": "0442d57ffa83985ec2ffaec95db9c0fe742f5182", + "rev": "5921ff72aa8019353091f0e63b3e34db28fa757f", "type": "github" }, "original": { @@ -112,16 +157,32 @@ "type": "github" } }, + "flake-compat_2": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, "flake-utils": { "inputs": { "systems": "systems" }, "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "lastModified": 1726560853, + "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=", "owner": "numtide", "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a", "type": "github" }, "original": { @@ -132,14 +193,14 @@ }, "flake-utils_2": { "inputs": { - "systems": "systems_3" + "systems": "systems_4" }, "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "lastModified": 1726560853, + "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=", "owner": "numtide", "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a", "type": "github" }, "original": { @@ -148,18 +209,61 @@ "type": "github" } }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "hyprland", + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, "home-manager": { + "inputs": { + "nixpkgs": [ + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1703113217, + "narHash": "sha256-7ulcXOk63TIT2lVDSExj7XzFx09LpdSAPtvgtM7yQPE=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "3bfaacf46133c037bb356193bd2f1765d9dc82c1", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "home-manager_2": { "inputs": { "nixpkgs": [ "nixpkgs" ] }, "locked": { - "lastModified": 1725694918, - "narHash": "sha256-+HsjshXpqNiJHLaJaK0JnIicJ/a1NquKcfn4YZ3ILgg=", + "lastModified": 1728726232, + "narHash": "sha256-8ZWr1HpciQsrFjvPMvZl0W+b0dilZOqXPoKa2Ux36bc=", "owner": "nix-community", "repo": "home-manager", - "rev": "aaebdea769a5c10f1c6e50ebdf5924c1a13f0cda", + "rev": "d57112db877f07387ce7104b5ac346ede556d2d7", "type": "github" }, "original": { @@ -184,11 +288,11 @@ ] }, "locked": { - "lastModified": 1722623071, - "narHash": "sha256-sLADpVgebpCBFXkA1FlCXtvEPu1tdEsTfqK1hfeHySE=", + "lastModified": 1727821604, + "narHash": "sha256-hNw5J6xatedqytYowx0mJKgctjA4lQARZFdgnzM2RpM=", "owner": "hyprwm", "repo": "hyprcursor", - "rev": "912d56025f03d41b1ad29510c423757b4379eb1c", + "rev": "d60e1e01e6e6633ef1c87148b9137cc1dd39263d", "type": "github" }, "original": { @@ -201,19 +305,21 @@ "inputs": { "aquamarine": "aquamarine", "hyprcursor": "hyprcursor", + "hyprland-protocols": "hyprland-protocols", "hyprlang": "hyprlang", "hyprutils": "hyprutils", "hyprwayland-scanner": "hyprwayland-scanner", "nixpkgs": "nixpkgs_2", - "systems": "systems_4", + "pre-commit-hooks": "pre-commit-hooks", + "systems": "systems_5", "xdph": "xdph" }, "locked": { - "lastModified": 1725667615, - "narHash": "sha256-ksmD1gNS/AX4qHvcCS7u+agvB+0fg2wCukFr3Hy4A3I=", + "lastModified": 1728752206, + "narHash": "sha256-r5xU/LqU4TrUOIouhYqrTZc1VY1zLQOOzbLsFCDlfpI=", "ref": "refs/heads/main", - "rev": "0500213086f8402ccbdb2acb4748dbc6d22e21f6", - "revCount": 5192, + "rev": "1822707c7e7394ce8c7572f2fe890763a307f499", + "revCount": 5332, "submodules": true, "type": "git", "url": "https://github.com/hyprwm/Hyprland" @@ -228,21 +334,19 @@ "inputs": { "nixpkgs": [ "hyprland", - "xdph", "nixpkgs" ], "systems": [ "hyprland", - "xdph", "systems" ] }, "locked": { - "lastModified": 1721326555, - "narHash": "sha256-zCu4R0CSHEactW9JqYki26gy8h9f6rHmSwj4XJmlHgg=", + "lastModified": 1728345020, + "narHash": "sha256-xGbkc7U/Roe0/Cv3iKlzijIaFBNguasI31ynL2IlEoM=", "owner": "hyprwm", "repo": "hyprland-protocols", - "rev": "5a11232266bf1a1f5952d5b179c3f4b2facaaa84", + "rev": "a7c183800e74f337753de186522b9017a07a8cee", "type": "github" }, "original": { @@ -267,11 +371,11 @@ ] }, "locked": { - "lastModified": 1725188252, - "narHash": "sha256-yBH8c4GDaEAtBrh+BqIlrx5vp6gG/Gu8fQQK63KAQgs=", + "lastModified": 1728168612, + "narHash": "sha256-AnB1KfiXINmuiW7BALYrKqcjCnsLZPifhb/7BsfPbns=", "owner": "hyprwm", "repo": "hyprlang", - "rev": "c12ab785ce1982f82594aff03b3104c598186ddd", + "rev": "f054f2e44d6a0b74607a6bc0f52dba337a3db38e", "type": "github" }, "original": { @@ -315,7 +419,7 @@ "hyprutils": "hyprutils_2", "hyprwayland-scanner": "hyprwayland-scanner_2", "nixpkgs": "nixpkgs_3", - "systems": "systems_5" + "systems": "systems_6" }, "locked": { "lastModified": 1725200438, @@ -343,11 +447,11 @@ ] }, "locked": { - "lastModified": 1724966483, - "narHash": "sha256-WXDgKIbzjYKczxSZOsJplCS1i1yrTUpsDPuJV/xpYLo=", + "lastModified": 1727300645, + "narHash": "sha256-OvAtVLaSRPnbXzOwlR1fVqCXR7i+ICRX3aPMCdIiv+c=", "owner": "hyprwm", "repo": "hyprutils", - "rev": "8976e3f6a5357da953a09511d0c7f6a890fb6ec2", + "rev": "3f5293432b6dc6a99f26aca2eba3876d2660665c", "type": "github" }, "original": { @@ -393,11 +497,11 @@ ] }, "locked": { - "lastModified": 1721324119, - "narHash": "sha256-SOOqIT27/X792+vsLSeFdrNTF+OSRp5qXv6Te+fb2Qg=", + "lastModified": 1726874836, + "narHash": "sha256-VKR0sf0PSNCB0wPHVKSAn41mCNVCnegWmgkrneKDhHM=", "owner": "hyprwm", "repo": "hyprwayland-scanner", - "rev": "a048a6cb015340bd82f97c1f40a4b595ca85cc30", + "rev": "500c81a9e1a76760371049a8d99e008ea77aa59e", "type": "github" }, "original": { @@ -433,11 +537,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1725432240, - "narHash": "sha256-+yj+xgsfZaErbfYM3T+QvEE2hU7UuE+Jf0fJCJ8uPS0=", + "lastModified": 1728492678, + "narHash": "sha256-9UTxR8eukdg+XZeHgxW5hQA9fIKHsKCdOIUycTryeVw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "ad416d066ca1222956472ab7d0555a6946746a80", + "rev": "5633bcff0c6162b9e4b5f1264264611e950c8ec7", "type": "github" }, "original": { @@ -449,11 +553,11 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1725407940, - "narHash": "sha256-tiN5Rlg/jiY0tyky+soJZoRzLKbPyIdlQ77xVgREDNM=", + "lastModified": 1728627514, + "narHash": "sha256-r+SF9AnHrTg+bk6YszoKfV9lgyw+yaFUQe0dOjI0Z2o=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "6f6c45b5134a8ee2e465164811e451dcb5ad86e3", + "rev": "c505ebf777526041d792a49d5f6dd4095ea391a7", "type": "github" }, "original": { @@ -465,11 +569,27 @@ }, "nixpkgs-stable_2": { "locked": { - "lastModified": 1725407940, - "narHash": "sha256-tiN5Rlg/jiY0tyky+soJZoRzLKbPyIdlQ77xVgREDNM=", + "lastModified": 1720386169, + "narHash": "sha256-NGKVY4PjzwAa4upkGtAMz1npHGoRzWotlSnVlqI40mo=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "194846768975b7ad2c4988bdb82572c00222c0d7", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable_3": { + "locked": { + "lastModified": 1728627514, + "narHash": "sha256-r+SF9AnHrTg+bk6YszoKfV9lgyw+yaFUQe0dOjI0Z2o=", "owner": "nixos", "repo": "nixpkgs", - "rev": "6f6c45b5134a8ee2e465164811e451dcb5ad86e3", + "rev": "c505ebf777526041d792a49d5f6dd4095ea391a7", "type": "github" }, "original": { @@ -479,13 +599,13 @@ "type": "github" } }, - "nixpkgs-stable_3": { + "nixpkgs-stable_4": { "locked": { - "lastModified": 1721524707, - "narHash": "sha256-5NctRsoE54N86nWd0psae70YSLfrOek3Kv1e8KoXe/0=", + "lastModified": 1728156290, + "narHash": "sha256-uogSvuAp+1BYtdu6UWuObjHqSbBohpyARXDWqgI12Ss=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "556533a23879fc7e5f98dd2e0b31a6911a213171", + "rev": "17ae88b569bb15590549ff478bab6494dde4a907", "type": "github" }, "original": { @@ -497,11 +617,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1725103162, - "narHash": "sha256-Ym04C5+qovuQDYL/rKWSR+WESseQBbNAe5DsXNx5trY=", + "lastModified": 1728018373, + "narHash": "sha256-NOiTvBbRLIOe5F6RbHaAh6++BNjsb149fGZd1T4+KBg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "12228ff1752d7b7624a54e9c1af4b222b3c1073b", + "rev": "bc947f541ae55e999ffdb4013441347d83b00feb", "type": "github" }, "original": { @@ -529,11 +649,11 @@ }, "nixpkgs_4": { "locked": { - "lastModified": 1725432240, - "narHash": "sha256-+yj+xgsfZaErbfYM3T+QvEE2hU7UuE+Jf0fJCJ8uPS0=", + "lastModified": 1728492678, + "narHash": "sha256-9UTxR8eukdg+XZeHgxW5hQA9fIKHsKCdOIUycTryeVw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "ad416d066ca1222956472ab7d0555a6946746a80", + "rev": "5633bcff0c6162b9e4b5f1264264611e950c8ec7", "type": "github" }, "original": { @@ -543,16 +663,41 @@ "type": "github" } }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": "flake-compat_2", + "gitignore": "gitignore", + "nixpkgs": [ + "hyprland", + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable_2" + }, + "locked": { + "lastModified": 1728092656, + "narHash": "sha256-eMeCTJZ5xBeQ0f9Os7K8DThNVSo9gy4umZLDfF5q6OM=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "1211305a5b237771e13fcca0c51e60ad47326a9a", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, "root": { "inputs": { "NixOS-WSL": "NixOS-WSL", + "agenix": "agenix", "ags": "ags", "emacs-overlay": "emacs-overlay", - "home-manager": "home-manager", + "home-manager": "home-manager_2", "hyprland": "hyprland", "hyprpaper": "hyprpaper", "nixpkgs": "nixpkgs_4", - "nixpkgs-stable": "nixpkgs-stable_2", + "nixpkgs-stable": "nixpkgs-stable_3", "sops-nix": "sops-nix" } }, @@ -561,14 +706,14 @@ "nixpkgs": [ "nixpkgs" ], - "nixpkgs-stable": "nixpkgs-stable_3" + "nixpkgs-stable": "nixpkgs-stable_4" }, "locked": { - "lastModified": 1725540166, - "narHash": "sha256-htc9rsTMSAY5ek+DB3tpntdD/es0eam2hJgO92bWSys=", + "lastModified": 1728345710, + "narHash": "sha256-lpunY1+bf90ts+sA2/FgxVNIegPDKCpEoWwOPu4ITTQ=", "owner": "Mic92", "repo": "sops-nix", - "rev": "d9d781523a1463965cd1e1333a306e70d9feff07", + "rev": "06535d0e3d0201e6a8080dd32dbfde339b94f01b", "type": "github" }, "original": { @@ -593,21 +738,6 @@ } }, "systems_2": { - "locked": { - "lastModified": 1689347949, - "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", - "owner": "nix-systems", - "repo": "default-linux", - "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default-linux", - "type": "github" - } - }, - "systems_3": { "locked": { "lastModified": 1681028828, "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", @@ -622,7 +752,7 @@ "type": "github" } }, - "systems_4": { + "systems_3": { "locked": { "lastModified": 1689347949, "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", @@ -637,6 +767,21 @@ "type": "github" } }, + "systems_4": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, "systems_5": { "locked": { "lastModified": 1689347949, @@ -652,13 +797,39 @@ "type": "github" } }, + "systems_6": { + "locked": { + "lastModified": 1689347949, + "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", + "owner": "nix-systems", + "repo": "default-linux", + "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default-linux", + "type": "github" + } + }, "xdph": { "inputs": { - "hyprland-protocols": "hyprland-protocols", + "hyprland-protocols": [ + "hyprland", + "hyprland-protocols" + ], "hyprlang": [ "hyprland", "hyprlang" ], + "hyprutils": [ + "hyprland", + "hyprutils" + ], + "hyprwayland-scanner": [ + "hyprland", + "hyprwayland-scanner" + ], "nixpkgs": [ "hyprland", "nixpkgs" @@ -669,11 +840,11 @@ ] }, "locked": { - "lastModified": 1725203932, - "narHash": "sha256-VLULC/OnI+6R9KEP2OIGk+uLJJsfRlaLouZ5gyFd2+Y=", + "lastModified": 1728166987, + "narHash": "sha256-w6dVTguAn9zJ+7aPOhBQgDz8bn6YZ7b56cY8Kg5HJRI=", "owner": "hyprwm", "repo": "xdg-desktop-portal-hyprland", - "rev": "2425e8f541525fa7409d9f26a8ffaf92a3767251", + "rev": "fb9c8d665af0588bb087f97d0f673ddf0d501787", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 9dc9d51b..0f8c01d3 100644 --- a/flake.nix +++ b/flake.nix @@ -3,8 +3,10 @@ description = "Sako's NixOS Configuration"; inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; # nixpkgs unstable branch - nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-24.05"; # nixpkgs stable branch because some things break + nixpkgs.url = + "github:NixOS/nixpkgs/nixos-unstable"; # nixpkgs unstable branch + nixpkgs-stable.url = + "github:nixos/nixpkgs/nixos-24.05"; # nixpkgs stable branch because some things break home-manager = { # this manages your dotfiles for the most part url = "github:nix-community/home-manager"; @@ -20,9 +22,11 @@ url = "github:Mic92/sops-nix"; inputs.nixpkgs.follows = "nixpkgs"; }; - emacs-overlay = { - url = "github:nix-community/emacs-overlay"; + agenix = { + url = "github:ryantm/agenix"; + inputs.nixpkgs.follows = "nixpkgs"; }; + emacs-overlay = { url = "github:nix-community/emacs-overlay"; }; ags = { url = "github:Aylur/ags"; inputs.nixpkgs.follows = "nixpkgs"; @@ -31,78 +35,53 @@ hyprpaper.url = "github:hyprwm/hyprpaper"; }; - outputs = { - self, - nixpkgs, - home-manager, - NixOS-WSL, - sops-nix, - emacs-overlay, - hyprland, - hyprpaper, - ags, - ... - } @ inputs: let - inherit (self) outputs; - forAllSystems = nixpkgs.lib.genAttrs [ - "x86_64-linux" - ]; - in rec { - # custom packages - packages = forAllSystems ( - system: let - pkgs = nixpkgs.legacyPackages.${system}; - in - import ./packages {inherit pkgs;} - ); - # dev shell for bootstrap - devShells = forAllSystems ( - system: let - pkgs = nixpkgs.legacyPackages.${system}; - in - import ./shell.nix {inherit pkgs;} - ); + outputs = { self, nixpkgs, home-manager, NixOS-WSL, agenix, emacs-overlay + , hyprland, hyprpaper, ags, ... }@inputs: + let + inherit (self) outputs; + forAllSystems = nixpkgs.lib.genAttrs [ "x86_64-linux" ]; + in rec { + # custom packages + packages = forAllSystems (system: + let pkgs = nixpkgs.legacyPackages.${system}; + in import ./packages { inherit pkgs; }); + # dev shell for bootstrap + devShells = forAllSystems (system: + let pkgs = nixpkgs.legacyPackages.${system}; + in import ./shell.nix { inherit pkgs; }); - # overlays here - overlays = import ./overlays {inherit inputs;}; + # overlays here + overlays = import ./overlays { inherit inputs; }; - # modules :D - nixosModules = import ./modules; + # modules :D + nixosModules = import ./modules; - nixosConfigurations = { - sakotop = nixpkgs.lib.nixosSystem { - specialArgs = {inherit inputs outputs;}; - modules = [ - ./default.nix - ./hosts/sakotop/configuration.nix - sops-nix.nixosModules.sops - ]; - }; - sakopc = nixpkgs.lib.nixosSystem { - specialArgs = {inherit inputs outputs;}; - modules = [ - ./default.nix - ./hosts/sakopc/configuration.nix - ]; - }; - #sakoserver = nixpkgs.lib.nixosSystem { - # specialArgs = {inherit inputs outputs;}; - # modules = [ - # ./default.nix - # ./hosts/sakoserver/configuration.nix - # ]; - #}; - sakowsl = nixpkgs.lib.nixosSystem { - # because theres no hardware-configuration.nix - system = "x86_64-linux"; - specialArgs = {inherit inputs outputs;}; - modules = [ - {nix.registry.nixpkgs.flake = nixpkgs;} - ./hosts/sakowsl/configuration.nix - NixOS-WSL.nixosModules.wsl - sops-nix.nixosModules.sops - ]; + nixosConfigurations = { + sakotop = nixpkgs.lib.nixosSystem { + specialArgs = { inherit inputs outputs; }; + modules = [ ./default.nix ./hosts/sakotop/configuration.nix ]; + }; + sakopc = nixpkgs.lib.nixosSystem { + specialArgs = { inherit inputs outputs; }; + modules = [ ./default.nix ./hosts/sakopc/configuration.nix ]; + }; + #sakoserver = nixpkgs.lib.nixosSystem { + # specialArgs = {inherit inputs outputs;}; + # modules = [ + # ./default.nix + # ./hosts/sakoserver/configuration.nix + # ]; + #}; + sakowsl = nixpkgs.lib.nixosSystem { + # because theres no hardware-configuration.nix + system = "x86_64-linux"; + specialArgs = { inherit inputs outputs; }; + modules = [ + { nix.registry.nixpkgs.flake = nixpkgs; } + ./hosts/sakowsl/configuration.nix + NixOS-WSL.nixosModules.wsl + ]; + }; }; }; - }; } diff --git a/hosts/sakopc/configuration.nix b/hosts/sakopc/configuration.nix index 6f207d07..e06aed99 100644 --- a/hosts/sakopc/configuration.nix +++ b/hosts/sakopc/configuration.nix @@ -1,10 +1,4 @@ -{ - config, pkgs, - lib, - inputs, - outputs, - ... -}: { +{ config, pkgs, lib, inputs, outputs, ... }: { imports = [ # Hardware Configuration # TODO:: Add this back once generated!!!!!!! @@ -25,8 +19,8 @@ hyprland.enable = true; foot.enable = true; kitty.enable = true; - picom.enable = true; - dunst.enable = true; + picom.enable = false; + dunst.enable = false; apps = { nextcloud.enable = true; rssguard.enable = true; @@ -39,7 +33,7 @@ browsers = { firefox.enable = true; qutebrowser.enable = false; - chromium.enable = true; + chromium.enable = false; }; chat = { zoom.enable = true; @@ -49,6 +43,8 @@ weechat.enable = true; signal.enable = true; element.enable = true; + gajim.enable = true; + psi-plus.enable = true; }; game = { lutris.enable = true; @@ -58,10 +54,11 @@ }; media = { mpv.enable = true; + ardour.enable = true; kdenlive.enable = true; blender.enable = true; feishin.enable = true; - jellyfin.enable = true; + jellyfin.enable = false; }; }; dev = { @@ -78,7 +75,7 @@ lua.enable = true; python.enable = true; rust.enable = true; - nil.enable = true; + nixd.enable = true; }; hardware = { bluetooth.enable = false; @@ -107,17 +104,22 @@ onlyoffice.enable = true; }; security = { - sops.enable = true; certs.enable = true; + tor.enable = true; }; }; # fuck you AOC # my monitor only works on 240hz now services.xserver.displayManager.setupCommands = '' - ${pkgs.xorg.xrandr}/bin/xrandr --output DP-0 --mode 1920x1080 --rate 239.96 --primary --output HDMI-0 --mode 1920x1080 --left-of DP-0 + ${pkgs.xorg.xrandr}/bin/xrandr --output DP-0 --mode 1920x1080 --rate 239.96 --primary --output HDMI-0 --mode 1920x1080 --left-of DP-0 ''; + # secrets + age.identityPaths = [ "/home/sako/.ssh/id_ed25519" ]; + + age.secrets.test.file = ../../secrets/test.age; + # lol services.xserver.dpi = 100; diff --git a/hosts/sakotop/configuration.nix b/hosts/sakotop/configuration.nix index 771b4849..1b83efef 100644 --- a/hosts/sakotop/configuration.nix +++ b/hosts/sakotop/configuration.nix @@ -1,13 +1,6 @@ # Edit this configuration file to define what should be installed on # your system. Help is available in the configuration.nix(5) man page and in the NixOS manual (accessible by running `nixos-help`). -{ - config, - pkgs, - lib, - inputs, - outputs, - ... -}: { +{ config, pkgs, lib, inputs, outputs, ... }: { imports = [ # Include the results of the hardware scan. ./hardware-configuration.nix @@ -46,6 +39,8 @@ telegram.enable = true; weechat.enable = true; element.enable = true; + gajim.enable = true; + psi-plus.enable = true; }; apps = { nemo.enable = true; @@ -64,6 +59,7 @@ lutris.enable = true; steam.enable = true; tetrio.enable = true; + osu.enable = true; prismlauncher.enable = true; }; media = { @@ -75,9 +71,7 @@ mpv.enable = true; jellyfin.enable = true; }; - security = { - wireshark.enable = true; - }; + security = { wireshark.enable = true; }; }; hardware = { nvidia = { @@ -101,7 +95,7 @@ package = pkgs.emacs-unstable-pgtk; }; }; - nil.enable = true; + nixd.enable = true; cc.enable = true; csharp.enable = true; javascript.enable = true; @@ -138,27 +132,18 @@ }; security = { age.enable = true; - sops.enable = true; certs.enable = true; + tor.enable = true; }; - virtualization = { - waydroid.enable = true; - }; + virtualization = { waydroid.enable = true; }; }; # Enable CUPS to print documents. # services.printing.enable = true; - services.xserver.videoDrivers = ["nvidia"]; + services.xserver.videoDrivers = [ "nvidia" ]; - # homelab - sops = { - # we need to setup wireguard with this soon - age.sshKeyPaths = ["/home/sako/.ssh/id_ed25519"]; - }; - - networking.wireguard.interfaces = { - }; + networking.wireguard.interfaces = { }; services.logind.extraConfig = '' # don’t shutdown when power button is short-pressed @@ -168,6 +153,10 @@ # set laptop dpi services.xserver.dpi = 100; + age.identityPaths = [ "/home/sako/.ssh/id_ed25519" ]; + + age.secrets.test.file = ../../secrets/test.age; + # Enable the OpenSSH daemon. # services.openssh.enable = true; diff --git a/hosts/sakowsl/configuration.nix b/hosts/sakowsl/configuration.nix index a90ac5dd..cd9aa25f 100644 --- a/hosts/sakowsl/configuration.nix +++ b/hosts/sakowsl/configuration.nix @@ -1,12 +1,4 @@ -{ - lib, - pkgs, - config, - modulesPath, - inputs, - outputs, - ... -}: { +{ lib, pkgs, config, modulesPath, inputs, outputs, ... }: { imports = [ inputs.home-manager.nixosModules.default "${modulesPath}/profiles/minimal.nix" @@ -49,38 +41,31 @@ nix.extraOptions = '' experimental-features = nix-command flakes ''; -# nix.settings.experimental-features = ["nix-command" "flakes"]; + # nix.settings.experimental-features = ["nix-command" "flakes"]; nix.settings = { - experimental-features = ["nix-command" "flakes"]; - substituters = [ - "https://cache.garnix.io" - "https://nix-community.cachix.org" - ]; + experimental-features = [ "nix-command" "flakes" ]; + substituters = + [ "https://cache.garnix.io" "https://nix-community.cachix.org" ]; trusted-public-keys = [ "cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g=" "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" ]; }; - # Home manager setup home-manager.useUserPackages = true; - home-manager.users.sako = {pkgs, ...}: { + home-manager.users.sako = { pkgs, ... }: { home.stateVersion = "22.05"; - home.packages = []; + home.packages = [ ]; home.username = "sako"; home.homeDirectory = "/home/sako"; - xdg.configFile.git = { - source = ../../config/git; - }; + xdg.configFile.git = { source = ../../config/git; }; # cure my sanity home.pointerCursor = { name = "Catppuccin-Mocha-Dark"; size = 16; - x11 = { - enable = true; - }; + x11 = { enable = true; }; gtk.enable = true; package = pkgs.catppuccin-cursors.mochaDark; }; @@ -97,16 +82,16 @@ programs.gnupg.agent = { enable = true; #pinentryPackage = null; - settings = { - # pinentry-program = "/mnt/c/Program Files (x86)/Gpg4win/bin/pinentry.exe"; + settings = { + # pinentry-program = "/mnt/c/Program Files (x86)/Gpg4win/bin/pinentry.exe"; allow-emacs-pinentry = ""; allow-loopback-pinentry = ""; - }; + }; }; # bare minimum environment.systemPackages = with pkgs; [ vim # backup - wget #double u get + wget # double u get killall # die processes unzip # zip file gh # github @@ -115,8 +100,6 @@ wsl-open # wsl-open ]; - environment.noXlibs = lib.mkForce false; - programs.git = { enable = true; package = pkgs.gitFull; @@ -128,9 +111,7 @@ nextcloud.enable = true; pass.enable = true; }; - chat = { - weechat.enable = true; - }; + chat = { weechat.enable = true; }; }; dev = { editors = { @@ -157,17 +138,13 @@ search.enable = true; }; }; - security = { - certs.enable = true; - }; + security = { certs.enable = true; }; }; services.gnome.gnome-keyring.enable = true; # for wsl-open - environment.sessionVariables = rec { - BROWSER = "wsl-open"; - }; + environment.sessionVariables = rec { BROWSER = "wsl-open"; }; security.sudo.wheelNeedsPassword = true; diff --git a/modules/desktop/browsers/firefox/default.nix b/modules/desktop/browsers/firefox/default.nix index 17d12069..015ffb1a 100644 --- a/modules/desktop/browsers/firefox/default.nix +++ b/modules/desktop/browsers/firefox/default.nix @@ -1,11 +1,5 @@ -{ - options, - config, - lib, - pkgs, - ... -}: let - cfg = config.modules.desktop.browsers.firefox; +{ options, config, lib, pkgs, ... }: +let cfg = config.modules.desktop.browsers.firefox; in { options.modules.desktop.browsers.firefox = { enable = lib.mkEnableOption false; @@ -34,38 +28,63 @@ in { # userChrome = '' # ''; - search.default = "DuckDuckGo"; + # search.default = "DuckDuckGo"; + search.default = "sakosearch"; search.force = true; search.engines = { "Nix Packages" = { - urls = [ - { - template = "https://search.nixos.org/packages?channel=unstable"; - params = [ - { - name = "query"; - value = "{searchTerms}"; - } - ]; - } - ]; - icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; - definedAliases = ["@nixpkgs"]; + urls = [{ + template = + "https://search.nixos.org/packages?channel=unstable"; + params = [{ + name = "query"; + value = "{searchTerms}"; + }]; + }]; + icon = + "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; + definedAliases = [ "@nixpkgs" ]; }; "Nix Options" = { - definedAliases = ["@nixopts"]; - icon = "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; - urls = [ - { - template = "https://search.nixos.org/options?channel=unstable"; - params = [ - { - name = "query"; - value = "{searchTerms}"; - } - ]; - } - ]; + definedAliases = [ "@nixopts" ]; + icon = + "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; + urls = [{ + template = + "https://search.nixos.org/options?channel=unstable"; + params = [{ + name = "query"; + value = "{searchTerms}"; + }]; + }]; + }; + "Home Manager Options" = { + definedAliases = [ "@homemgropts" ]; + icon = + "${pkgs.nixos-icons}/share/icons/hicolor/scalable/apps/nix-snowflake.svg"; + urls = [{ + template = + "https://home-manager-options.extranix.com/?release=master"; + params = [{ + name = "query"; + value = "{searchTerms}"; + }]; + }]; + }; + "sakosearch" = { + definedAliases = [ "@sakosearch" ]; + icon = pkgs.fetchurl { + url = + "https://raw.githubusercontent.com/searxng/searxng/refs/heads/master/src/brand/searxng-wordmark.svg"; + hash = "sha256-TwwPUNL+IRRjLY7Xmd466F474vglkvpJUYa+fBwDzFI="; + }; + urls = [{ + template = "https://search.sako.box/search"; + params = [{ + name = "q"; + value = "{searchTerms}"; + }]; + }]; }; }; }; diff --git a/modules/desktop/chat/default.nix b/modules/desktop/chat/default.nix index 923077b5..b9bfc569 100644 --- a/modules/desktop/chat/default.nix +++ b/modules/desktop/chat/default.nix @@ -8,5 +8,8 @@ ./signal ./cinny ./element + ./gajim + ./pidgin + ./psiplus ]; } diff --git a/modules/desktop/chat/gajim/default.nix b/modules/desktop/chat/gajim/default.nix new file mode 100644 index 00000000..5e83e76f --- /dev/null +++ b/modules/desktop/chat/gajim/default.nix @@ -0,0 +1,10 @@ +{ outputs, options, config, lib, pkgs, ... }: +let cfg = config.modules.desktop.chat.gajim; +in { + options.modules.desktop.chat.gajim = { enable = lib.mkEnableOption false; }; + + config = lib.mkIf cfg.enable { + users.users.sako.packages = with pkgs; [ gajim ]; + + }; +} diff --git a/modules/desktop/chat/pidgin/default.nix b/modules/desktop/chat/pidgin/default.nix new file mode 100644 index 00000000..e1596c9b --- /dev/null +++ b/modules/desktop/chat/pidgin/default.nix @@ -0,0 +1,15 @@ +{ outputs, options, config, lib, pkgs, ... }: +let cfg = config.modules.desktop.chat.pidgin; +in { + options.modules.desktop.chat.pidgin = { enable = lib.mkEnableOption false; }; + + config = lib.mkIf cfg.enable { + users.users.sako.packages = with pkgs; + [ + (pidgin.override { + plugins = + [ pidginPackages.pidgin-otr pidginPackages.pidgin-indicator ]; + }) + ]; + }; +} diff --git a/modules/desktop/chat/psiplus/default.nix b/modules/desktop/chat/psiplus/default.nix new file mode 100644 index 00000000..0e8bfc70 --- /dev/null +++ b/modules/desktop/chat/psiplus/default.nix @@ -0,0 +1,12 @@ +{ outputs, options, config, lib, pkgs, ... }: +let cfg = config.modules.desktop.chat.psi-plus; +in { + options.modules.desktop.chat.psi-plus = { + enable = lib.mkEnableOption false; + }; + + config = lib.mkIf cfg.enable { + users.users.sako.packages = with pkgs; [ psi-plus ]; + + }; +} diff --git a/modules/desktop/default.nix b/modules/desktop/default.nix index e604c43c..89251b90 100644 --- a/modules/desktop/default.nix +++ b/modules/desktop/default.nix @@ -3,10 +3,8 @@ # window managers ./awesome ./bspwm - ./dwm ./hyprland ./xmonad - ./qtile ./exwm ./i3 # desktop environ men t s s s s diff --git a/modules/desktop/dwm/default.nix b/modules/desktop/dwm/default.nix deleted file mode 100644 index 2a1a0136..00000000 --- a/modules/desktop/dwm/default.nix +++ /dev/null @@ -1,110 +0,0 @@ -{ - outputs, - options, - config, - lib, - pkgs, - ... -}: -let - cfg = config.modules.desktop.dwm; -in { - options.modules.desktop.dwm = { - enable = lib.mkEnableOption false; - }; - - config = lib.mkIf cfg.enable { - # this needs to be enabled for gtk apps - programs.dconf.enable = true; - # enable dwm - services.displayManager.defaultSession = "none+dwm"; - - services.xserver = { - enable = true; - windowManager = { - dwm.enable = true; - }; - displayManager = { - lightdm = { - enable = true; - background = ../../../config/background.png; - greeters.gtk = { - enable = true; - theme = { - name = "vimix-dark-ruby"; - package = pkgs.vimix-gtk-themes; - }; - cursorTheme = { - name = "Catppuccin-Mocha-Dark"; - size = 16; - package = pkgs.catppuccin-cursors.mochaDark; - }; - }; - # greeters.mini = { - # enable = true; - # user = "sako"; - # extraConfig = '' - # [greeter] - # show-password-label = true - # password-label-text = magic word - # invalid-password-text = skull issue - # ''; - # }; - }; - }; - }; - - services.libinput = { - mouse = { - accelProfile = "flat"; - }; - - touchpad = { - accelProfile = "flat"; - }; - }; - users.users.sako.packages = with pkgs; [ - rofi - # network - networkmanagerapplet - # brightness - brightnessctl - # gee tee k - vimix-gtk-themes - vimix-icon-theme - lxappearance - catppuccin-cursors.mochaDark - # screen shot (s) - flameshot - # clipboard - xclip - ]; - home-manager.users.sako = {pkgs, ...}: { - home.file = { - "background.png" = { - enable = true; - source = ../../../config/background.png; - }; - ".dwmscripts" = { - enable = true; - recursive = true; - source = ../../../config/dwmbar; - }; - }; - home.pointerCursor = { - name = "Catppuccin-Mocha-Dark"; - size = 16; - x11 = { - enable = true; - }; - gtk.enable = true; - package = pkgs.catppuccin-cursors.mochaDark; - }; - gtk = { - enable = true; - theme.name = "vimix-dark-ruby"; - iconTheme.name = "Vimix Ruby Dark"; - }; - }; - }; -} diff --git a/modules/desktop/foot/default.nix b/modules/desktop/foot/default.nix index 8c33ae85..5fe06ad5 100644 --- a/modules/desktop/foot/default.nix +++ b/modules/desktop/foot/default.nix @@ -1,23 +1,55 @@ -{ options, config, lib, pkgs, ...}: -let - cfg = config.modules.desktop.foot; +{ options, config, lib, pkgs, ... }: +let cfg = config.modules.desktop.foot; in { - options.modules.desktop.foot = { - enable = lib.mkEnableOption false; - }; + options.modules.desktop.foot = { enable = lib.mkEnableOption false; }; config = lib.mkIf cfg.enable { - users.users.sako.packages = with pkgs; [ - foot - ]; + users.users.sako.packages = with pkgs; [ foot ]; - home-manager.users.sako = {pkgs, ...}: { - xdg.configFile = { - foot = { - source = ../../../config/foot; + home-manager.users.sako = { pkgs, ... }: { + programs.foot = { + enable = true; + server.enable = false; + settings = { + main = { + term = "xterm-256color"; + font = "JetBrainsMono NF:size=12"; + }; + scrollback = { lines = 1000; }; + cursor = { + style = "block"; + blink = "yes"; + blink-rate = "1000"; + }; + mouse = { hide-when-typing = "yes"; }; + colors = { + alpha = "1.0"; + background = "010000"; + foreground = "bfbfbf"; + + # Normal/Regular colors (0-7) + regular0 = "010000"; + regular1 = "67514A"; + regular2 = "6A5D4E"; + regular3 = "9B686A"; + regular4 = "9F8975"; + regular5 = "BD7D81"; + regular6 = "D07789"; + regular7 = "bfbfbf"; + + # Bright colors (8-15) + bright0 = "615050"; + bright1 = "67514A"; + bright2 = "6A5D4E"; + bright3 = "9B686A"; + bright4 = "9F8975"; + bright5 = "BD7D81"; + bright6 = "D07788"; + bright7 = "bfbfbf"; + }; + }; }; }; }; - }; } diff --git a/modules/desktop/game/default.nix b/modules/desktop/game/default.nix index 152ba717..1a840186 100644 --- a/modules/desktop/game/default.nix +++ b/modules/desktop/game/default.nix @@ -1,10 +1,4 @@ { - imports = [ - ./steam - ./lutris - ./wine - ./grapejuice - ./tetrio - ./prismlauncher - ]; + imports = + [ ./steam ./lutris ./wine ./grapejuice ./tetrio ./prismlauncher ./osu ]; } diff --git a/modules/desktop/game/osu/default.nix b/modules/desktop/game/osu/default.nix new file mode 100644 index 00000000..11287ac8 --- /dev/null +++ b/modules/desktop/game/osu/default.nix @@ -0,0 +1,9 @@ +{ outputs, options, config, lib, pkgs, ... }: +let cfg = config.modules.desktop.game.osu; +in { + options.modules.desktop.game.osu = { enable = lib.mkEnableOption false; }; + + config = lib.mkIf cfg.enable { + users.users.sako.packages = with pkgs; [ osu-lazer-bin ]; + }; +} diff --git a/modules/desktop/game/tetrio/default.nix b/modules/desktop/game/tetrio/default.nix index f04913ab..5d6f6021 100644 --- a/modules/desktop/game/tetrio/default.nix +++ b/modules/desktop/game/tetrio/default.nix @@ -15,9 +15,10 @@ in { config = lib.mkIf cfg.enable { users.users.sako.packages = with pkgs; [ - (tetrio-desktop.override { - withTetrioPlus = true; - }) + # (tetrio-desktop.override { + # withTetrioPlus = true; + # }) + tetrio-desktop ]; }; } diff --git a/modules/desktop/hyprland/default.nix b/modules/desktop/hyprland/default.nix index c85e0c8e..8036a82f 100644 --- a/modules/desktop/hyprland/default.nix +++ b/modules/desktop/hyprland/default.nix @@ -1,80 +1,69 @@ -{ inputs, outputs, options, config, lib, pkgs, ...}: -let - cfg = config.modules.desktop.hyprland; -in -{ - imports = [ - inputs.hyprland.nixosModules.default - ]; +{ inputs, outputs, options, config, lib, pkgs, ... }: +let cfg = config.modules.desktop.hyprland; +in { + imports = [ inputs.hyprland.nixosModules.default ]; - options.modules.desktop.hyprland = { - enable = lib.mkEnableOption false; - }; + options.modules.desktop.hyprland = { enable = lib.mkEnableOption false; }; config = lib.mkIf cfg.enable { - modules.desktop.dunst.enable = lib.mkForce false; + modules.desktop.dunst.enable = lib.mkForce false; - services.gnome.gnome-keyring.enable = true; + services.gnome.gnome-keyring.enable = true; - services.greetd = { - enable = true; - settings = { - terminal = { - vt = 2; - }; - default_session = { - command = "${pkgs.greetd.tuigreet}/bin/tuigreet --time --time-format '%I:%M %p | %a • %h | %F' --cmd Hyprland"; - user = "greeter"; + services.greetd = { + enable = true; + settings = { + terminal = { vt = 2; }; + default_session = { + command = + "${pkgs.greetd.tuigreet}/bin/tuigreet --time --time-format '%I:%M %p | %a • %h | %F' --cmd Hyprland"; + user = "greeter"; + }; }; }; - }; - # https://github.com/apognu/tuigreet/issues/68#issuecomment-1586359960 - # make greetd not have systemd logs overlap - systemd.services.greetd.serviceConfig = { - Type = "idle"; - StandardInput = "tty"; - StandardOutput = "tty"; - StandardError = "journal"; # Without this errors will spam on screen - # Without these bootlogs will spam on screen - TTYReset = true; - TTYVHangup = true; - TTYVTDisallocate = true; - }; + # https://github.com/apognu/tuigreet/issues/68#issuecomment-1586359960 + # make greetd not have systemd logs overlap + systemd.services.greetd.serviceConfig = { + Type = "idle"; + StandardInput = "tty"; + StandardOutput = "tty"; + StandardError = "journal"; # Without this errors will spam on screen + # Without these bootlogs will spam on screen + TTYReset = true; + TTYVHangup = true; + TTYVTDisallocate = true; + }; - services.xserver = { + services.xserver = { + enable = true; + # displayManager = { + # # lightdm = { + # # enable = true; + # # background = ../../../config/background.png; + # # greeters.gtk = { + # # enable = true; + # # theme = { + # # name = "vimix-dark-ruby"; + # # package = pkgs.vimix-gtk-themes; + # # }; + # # }; + # # }; + # gdm = { + # enable = true; + # }; + # }; + }; + services.libinput = { enable = true; - # displayManager = { -# # lightdm = { -# # enable = true; -# # background = ../../../config/background.png; -# # greeters.gtk = { -# # enable = true; -# # theme = { -# # name = "vimix-dark-ruby"; -# # package = pkgs.vimix-gtk-themes; -# # }; -# # }; -# # }; - # gdm = { - # enable = true; - # }; - # }; - }; - services.libinput = { - enable = true; - # no mouse accel - mouse = { - accelProfile = "flat"; - }; + # no mouse accel + mouse = { accelProfile = "flat"; }; - # no touchpad accel - touchpad = { - accelProfile = "flat"; - }; - }; + # no touchpad accel + touchpad = { accelProfile = "flat"; }; + }; users.users.sako.packages = with pkgs; [ # use wayland counterparts @@ -114,9 +103,7 @@ in wl-clipboard ]; - programs.hyprland = { - enable = true; - }; + programs.hyprland = { enable = true; }; programs.hyprlock.enable = true; @@ -126,7 +113,7 @@ in # piece of shit thanks! services.emacs.startWithGraphical = false; - home-manager.users.sako = { pkgs , ...}: { + home-manager.users.sako = { pkgs, ... }: { home.pointerCursor = { # name = "Catppuccin-Mocha-Dark"; name = "catppuccin-mocha-dark-cursors"; @@ -136,10 +123,10 @@ in }; gtk = { enable = true; - theme.name = "Fluent-red-Dark"; - iconTheme.name = "Fluent-red-dark"; + theme.name = "Fluent-pink-Dark"; + iconTheme.name = "Fluent-pink-dark"; }; - home.file = { + home.file = { "background.png" = { enable = true; source = ../../../config/background.png; @@ -148,12 +135,13 @@ in # thanks PartyWumpus # https://github.com/PartyWumpus/dotfiles/blob/277949d84d53a58a3f52be935cd3c581c89d5d7c/modules/hyprland/hyprland.nix#L492 "/nixos/config/ags/types" = { - source = "${inputs.ags.packages.x86_64-linux.agsWithTypes.out}/share/com.github.Aylur.ags/types"; + source = + "${inputs.ags.packages.x86_64-linux.agsWithTypes.out}/share/com.github.Aylur.ags/types"; }; }; xdg.configFile = { hypr = { - source = ../../../config/hyprland; + source = ../../../config/hyprland; recursive = true; }; waybar = { @@ -168,7 +156,7 @@ in source = ../../../config/ags; recursive = true; }; - }; + }; }; environment.sessionVariables.NIXOS_OZONE_WL = "1"; diff --git a/modules/desktop/media/ardour/default.nix b/modules/desktop/media/ardour/default.nix new file mode 100644 index 00000000..f47b9069 --- /dev/null +++ b/modules/desktop/media/ardour/default.nix @@ -0,0 +1,15 @@ +{ outputs, options, config, lib, pkgs, ...}: +let + cfg = config.modules.desktop.media.ardour; +in +{ + options.modules.desktop.media.ardour = { + enable = lib.mkEnableOption false; + }; + + config = lib.mkIf cfg.enable { + users.users.sako.packages = with pkgs; [ + ardour + ]; + }; +} diff --git a/modules/desktop/media/default.nix b/modules/desktop/media/default.nix index 8c705539..3c37e70f 100644 --- a/modules/desktop/media/default.nix +++ b/modules/desktop/media/default.nix @@ -6,6 +6,7 @@ ./blender ./kdenlive ./lmms + ./ardour ./mpv ./jellyfin ./feishin diff --git a/modules/desktop/qtile/default.nix b/modules/desktop/qtile/default.nix deleted file mode 100644 index 8b2b8cc6..00000000 --- a/modules/desktop/qtile/default.nix +++ /dev/null @@ -1,97 +0,0 @@ -{ - outputs, - options, - config, - lib, - pkgs, - ... -}: -let - cfg = config.modules.desktop.qtile; -in { - options.modules.desktop.qtile = { - enable = lib.mkEnableOption false; - }; - - #TODO Do this - - config = lib.mkIf cfg.enable { - services.xserver = { - enable = true; - windowManager.qtile = { - enable = true; - }; - displayManager = { - defaultSession = "none+qtile"; - lightdm = { - enable = true; - background = ../../../config/background.png; - greeters.gtk = { - enable = true; - theme = { - name = "vimix-dark-ruby"; - package = pkgs.vimix-gtk-themes; - }; - }; - }; - }; - libinput = { - enable = true; - - # no mouse accel - mouse = { - accelProfile = "flat"; - }; - - # no touchpad accel - touchpad = { - accelProfile = "flat"; - }; - }; - }; - users.users.sako.packages = with pkgs; [ - rofi - # network - networkmanagerapplet - # brightness - brightnessctl - # gee tee k - vimix-gtk-themes - vimix-icon-theme - lxappearance - catppuccin-cursors.mochaDark - # screen shot (s) - flameshot - ]; - - home-manager.users.sako = {pkgs, ...}: { - home.pointerCursor = { - name = "Catppuccin-Mocha-Dark"; - size = 16; - x11 = { - enable = true; - }; - gtk.enable = true; - package = pkgs.catppuccin-cursors.mochaDark; - }; - gtk = { - enable = true; - theme.name = "vimix-dark-ruby"; - iconTheme.name = "Vimix Ruby Dark"; - }; - home.file = { - "background.png" = { - enable = true; - source = ../../../config/background.png; - }; - }; - #xdg.configFile = { - # qtile = { - # enable = true; - # source = ../../../config/qtile; - # recursive = true; - # }; - #}; - }; - }; -} diff --git a/modules/desktop/wireguard/default.nix b/modules/desktop/wireguard/default.nix index 0120a996..3f77616e 100644 --- a/modules/desktop/wireguard/default.nix +++ b/modules/desktop/wireguard/default.nix @@ -16,5 +16,10 @@ in { config = lib.mkIf cfg.enable { # todo declaritivly setting it up networking.wireguard.enable = true; + + users.users.sako.packages = with pkgs; [ + openresolv + ]; + }; } diff --git a/modules/dev/editors/emacs/default.nix b/modules/dev/editors/emacs/default.nix index 498607e3..9b15409a 100644 --- a/modules/dev/editors/emacs/default.nix +++ b/modules/dev/editors/emacs/default.nix @@ -1,15 +1,15 @@ -{ - outputs, - options, - config, - lib, - pkgs, - inputs, - ... -}: +{ outputs, options, config, lib, pkgs, inputs, ... }: let cfg = config.modules.dev.editors.emacs; + inherit (lib) mkForce; + + # so we dont cry later on why texLive is MASSIVE + tex = (pkgs.texlive.combine { + inherit (pkgs.texlive) + scheme-basic dvisvgm dvipng # for preview and export as html + wrapfig amsmath ulem hyperref capt-of fontspec inputenx graphics etoolbox; + }); myEmacs = pkgs.emacsWithPackagesFromUsePackage { config = ../../../../config/emacs/emacs.org; @@ -21,54 +21,54 @@ let epkgs.mu4e # TODO make this check if EXWM is enabled or not epkgs.exwm -# epkgs.sakomodules + # epkgs.sakomodules epkgs.eglot-booster epkgs.app-launcher ]; # add eglot-lsp-booster package - override = epkgs: epkgs // { - eglot-booster = epkgs.trivialBuild { - pname = "eglot-booster"; - version = "e19dd7ea81bada84c66e8bdd121408d9c0761fe6"; + override = epkgs: + epkgs // { + eglot-booster = epkgs.trivialBuild { + pname = "eglot-booster"; + version = "e19dd7ea81bada84c66e8bdd121408d9c0761fe6"; - packageRequires = with pkgs; [ emacs-lsp-booster ]; + packageRequires = with pkgs; [ emacs-lsp-booster ]; - src = pkgs.fetchFromGitHub { - owner = "jdtsmith"; - repo = "eglot-booster"; - rev = "e19dd7ea81bada84c66e8bdd121408d9c0761fe6"; - hash = "sha256-vF34ZoUUj8RENyH9OeKGSPk34G6KXZhEZozQKEcRNhs="; + src = pkgs.fetchFromGitHub { + owner = "jdtsmith"; + repo = "eglot-booster"; + rev = "e19dd7ea81bada84c66e8bdd121408d9c0761fe6"; + hash = "sha256-vF34ZoUUj8RENyH9OeKGSPk34G6KXZhEZozQKEcRNhs="; + }; + }; + app-launcher = epkgs.melpaBuild { + pname = "app-launcher"; + version = "1.0"; + + commit = "d5015e394b0a666a8c7c4d4bdf786266e773b145"; + + recipe = pkgs.writeText "recipe" '' + (app-launcher :repo "SebastienWae/app-launcher" :fetcher github) + ''; + + src = pkgs.fetchFromGitHub { + owner = "SebastienWae"; + repo = "app-launcher"; + rev = "d5015e394b0a666a8c7c4d4bdf786266e773b145"; + hash = "sha256-d0d5rkuxK/zKpSCa1UTdpV7o+RDDsEeab56rI7xUJ1E="; + }; + }; }; - }; - app-launcher = epkgs.melpaBuild { - pname = "app-launcher"; - version = "1.0"; - - - commit = "d5015e394b0a666a8c7c4d4bdf786266e773b145"; - - recipe = pkgs.writeText "recipe" '' - (app-launcher :repo "SebastienWae/app-launcher" :fetcher github) - ''; - - src = pkgs.fetchFromGitHub { - owner = "SebastienWae"; - repo = "app-launcher"; - rev = "d5015e394b0a666a8c7c4d4bdf786266e773b145"; - hash = "sha256-d0d5rkuxK/zKpSCa1UTdpV7o+RDDsEeab56rI7xUJ1E="; - }; - }; - }; # override for modules -# override = epkgs: epkgs // { -# sakomodules = epkgs.trivialBuild { -# pname = "sakomodules"; -# version = "lol"; + # override = epkgs: epkgs // { + # sakomodules = epkgs.trivialBuild { + # pname = "sakomodules"; + # version = "lol"; -# src = ../../../../config/emacs/modules; + # src = ../../../../config/emacs/modules; -# }; -# }; + # }; + # }; }; in { options.modules.dev.editors.emacs = { @@ -82,9 +82,7 @@ in { }; config = lib.mkIf cfg.enable { - nixpkgs.overlays = [ - inputs.emacs-overlay.overlay - ]; + nixpkgs.overlays = [ inputs.emacs-overlay.overlay ]; # ues daemon services.emacs = { enable = cfg.daemon; @@ -107,18 +105,27 @@ in { direnv # mu for email mu - # sync - isync - cyrus-sasl-xoauth2 + # email sync + offlineimap + (isync.override { withCyrusSaslXoauth2 = true; }) + # oauth + oama # protonmail hydroxide + # send mail + msmtp # doc-view unoconv # org to pdf - # this might be bloat... - texliveMinimal + tex # lsp emacs-lsp-booster + # zenity-color-picker + zenity + # org-wild-notifier + libnotify + # wakatime-mode + wakatime-cli ]; systemd.services.hydroxide = { @@ -140,20 +147,24 @@ in { # }; # }; - home-manager.users.sako = {lib, ...}: { + home-manager.users.sako = { lib, ... }: { home.file = { - ".emacs.d/init.el".source = pkgs.runCommand "init.el" {} '' + ".emacs.d/init.el".source = pkgs.runCommand "init.el" { } '' cp ${../../../../config/emacs/emacs.org} emacs.org - ${pkgs.emacs}/bin/emacs -Q --batch ./emacs.org -f org-babel-tangle + ${myEmacs}/bin/emacs -Q --batch ./emacs.org -f org-babel-tangle mv init.el $out ''; ".emacs.d/icon.png".source = ../../../../config/emacs/icon.png; - ".mbsyncrc".source = ../../../../config/emacs/.mbsyncrc; + # ".mbsyncrc".source = ../../../../config/emacs/.mbsyncrc; + ".offlineimaprc".source = ../../../../config/emacs/.offlineimaprc; + ".offlineimap.py".source = ../../../../config/emacs/.offlineimap.py; }; }; + programs.gnupg.agent.pinentryPackage = mkForce pkgs.pinentry-emacs; + fonts.packages = with pkgs; [ - (nerdfonts.override {fonts = ["JetBrainsMono"];}) + (nerdfonts.override { fonts = [ "JetBrainsMono" ]; }) jetbrains-mono ]; }; diff --git a/modules/dev/nil.nix b/modules/dev/nil.nix index d3432f95..e6048c00 100644 --- a/modules/dev/nil.nix +++ b/modules/dev/nil.nix @@ -11,6 +11,7 @@ in environment.systemPackages = with pkgs; [ nil alejandra + nixfmt ]; }; } diff --git a/modules/dev/nixd.nix b/modules/dev/nixd.nix index 6796ed31..f088cd65 100644 --- a/modules/dev/nixd.nix +++ b/modules/dev/nixd.nix @@ -1,26 +1,13 @@ # nixd nix lsp using nix and nixpkgs # where has this been my whole life -{ - outputs, - options, - config, - lib, - pkgs, - ... -}: -let - cfg = config.modules.dev.nixd; +{ outputs, options, config, lib, pkgs, ... }: +let cfg = config.modules.dev.nixd; in { - options.modules.dev.nixd = { - enable = lib.mkEnableOption false; - }; + options.modules.dev.nixd = { enable = lib.mkEnableOption false; }; # TODO(sako):: figure out how .nixd.json works config = lib.mkIf cfg.enable { - environment.systemPackages = with pkgs; [ - unstable.nixd - alejandra - ]; + environment.systemPackages = with pkgs; [ nixd alejandra nixfmt ]; }; } diff --git a/modules/hardware/pipewire/default.nix b/modules/hardware/pipewire/default.nix index db0333d7..24c3f47d 100644 --- a/modules/hardware/pipewire/default.nix +++ b/modules/hardware/pipewire/default.nix @@ -1,11 +1,7 @@ -{ outputs, options, config, lib, pkgs, ...}: -let - cfg = config.modules.hardware.pipewire; -in -{ - options.modules.hardware.pipewire = { - enable = lib.mkEnableOption false; - }; +{ outputs, options, config, lib, pkgs, ... }: +let cfg = config.modules.hardware.pipewire; +in { + options.modules.hardware.pipewire = { enable = lib.mkEnableOption false; }; config = lib.mkIf cfg.enable { # resolve racial conflict between @@ -23,9 +19,13 @@ in enable = true; alsa.enable = true; alsa.support32Bit = true; + jack.enable = true; pulse.enable = true; }; - + + # unsupported apps that use these + environment.systemPackages = with pkgs; [ pulseaudio alsa-utils pamixer ]; + }; } diff --git a/modules/security/default.nix b/modules/security/default.nix index eab72ed0..d6b784c6 100644 --- a/modules/security/default.nix +++ b/modules/security/default.nix @@ -1,7 +1 @@ -{ - imports = [ - ./age.nix - ./sops.nix - ./certs - ]; -} +{ imports = [ ./age.nix ./certs ./tor.nix ]; } diff --git a/modules/security/sops.nix b/modules/security/sops.nix deleted file mode 100644 index 6ac09427..00000000 --- a/modules/security/sops.nix +++ /dev/null @@ -1,21 +0,0 @@ -{ - outputs, - options, - config, - lib, - pkgs, - ... -}: -let - cfg = config.modules.security.age; -in { - options.modules.security.sops = { - enable = lib.mkEnableOption false; - }; - - config = lib.mkIf cfg.enable { - environment.systemPackages = with pkgs; [ - sops - ]; - }; -} diff --git a/modules/security/tor.nix b/modules/security/tor.nix new file mode 100644 index 00000000..33b3be70 --- /dev/null +++ b/modules/security/tor.nix @@ -0,0 +1,25 @@ +{ outputs, options, config, lib, pkgs, ... }: +let cfg = config.modules.security.tor; +in { + options.modules.security.tor = { enable = lib.mkEnableOption false; }; + + config = lib.mkIf cfg.enable { + + age.secrets.torrc = { + file = ../../secrets/shared/torrc.age; + owner = "tor"; + group = "tor"; + }; + + users.users.sako.packages = with pkgs; [ tor-browser ]; + + services.tor = { + enable = true; + torsocks.enable = true; + client = { enable = true; }; + }; + + environment.etc = { "tor/torrc".source = config.age.secrets.torrc.path; }; + + }; +} diff --git a/modules/server/default.nix b/modules/server/default.nix index 76a2a9f7..d82cf401 100644 --- a/modules/server/default.nix +++ b/modules/server/default.nix @@ -1,17 +1,10 @@ -{ - config, - lib, - ... -}: -with lib; let - cfg = config.modules.server; +{ config, lib, ... }: +with lib; +let cfg = config.modules.server; in { - imports = [ - ]; + imports = [ ]; - options.modules.server = { - isServer = mkEnableOption false; - }; + options.modules.server = { isServer = mkEnableOption false; }; config = mkIf cfg.isServer { # we need this if you say otherwise ill throw you @@ -23,11 +16,13 @@ in { PermitRootLogin = "no"; # its so easy to use keys your grandmother could use it PasswordAuthentication = false; - ports = [ - 69 - ]; + ports = [ 69 ]; openFirewall = true; }; }; + + users.users.sako.openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPGAwG2Fqs3xNF/6/9GdznH/jUIqxW3aTYvmteuq9odZ sako@sakotop" + ]; }; } diff --git a/modules/virtualization/default.nix b/modules/virtualization/default.nix index 4dbde113..5f00db20 100644 --- a/modules/virtualization/default.nix +++ b/modules/virtualization/default.nix @@ -1,5 +1,6 @@ { imports = [ ./waydroid.nix + ./virt-manager.nix ]; } diff --git a/modules/virtualization/virt-manager.nix b/modules/virtualization/virt-manager.nix index ed1ea5b4..67bcc5cc 100644 --- a/modules/virtualization/virt-manager.nix +++ b/modules/virtualization/virt-manager.nix @@ -8,12 +8,8 @@ in }; config = lib.mkIf cfg.enable { - virtualization.libvirtd.enable = true; - programs.dconf.enable = true; - environtment.systemPackages = with pkgs; [ - virt-manager - ]; - - users.users.sako.extraGroups = [ "libvirtd" ]; + virtualisation.libvirtd.enable = true; + programs.virt-manager.enable = true; + users.users.sako.extraGroups = [ "libvirtd" ]; }; } diff --git a/overlays/default.nix b/overlays/default.nix index 2a1c2cd5..61f24578 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -1,10 +1,8 @@ -{inputs, ...}: { +{ inputs, ... }: { # This one brings our custom packages from the 'pkgs' directory - additions = final: _prev: import ../packages {pkgs = final;}; + additions = final: _prev: import ../packages { pkgs = final; }; - nixpkgs.overlays = [ - inputs.emacs-overlay - ]; + nixpkgs.overlays = [ inputs.emacs-overlay ]; # This one contains whatever you want to overlay # You can change versions, add patches, set compilation flags, anything really. # https://nixos.wiki/wiki/Overlays @@ -12,35 +10,23 @@ # example = prev.example.overrideAttrs (oldAttrs: rec { # ... # }); - polybar = prev.polybar.override { - pulseSupport = true; - }; - qutebrowser = prev.qutebrowser.override { - enableWideVine = true; - }; - vimix-gtk-themes = prev.vimix-gtk-themes.override { - themeVariants = ["ruby"]; - }; + polybar = prev.polybar.override { pulseSupport = true; }; + qutebrowser = prev.qutebrowser.override { enableWideVine = true; }; + vimix-gtk-themes = + prev.vimix-gtk-themes.override { themeVariants = [ "ruby" ]; }; fluent-gtk-theme = prev.fluent-gtk-theme.override { colorVariants = [ "dark" ]; - themeVariants = [ "red" ]; + themeVariants = [ "pink" ]; tweaks = [ "square" ]; }; - fluent-icon-theme = prev.fluent-icon-theme.override { - colorVariants = [ "red" ]; - }; - dwm = prev.dwm.overrideAttrs (old: { - src = ../config/dwm; - }); + fluent-icon-theme = + prev.fluent-icon-theme.override { colorVariants = [ "pink" ]; }; + dwm = prev.dwm.overrideAttrs (old: { src = ../config/dwm; }); ags = prev.ags.overrideAttrs (old: { - buildInputs = old.buildInputs ++ [ inputs.nixpkgs.legacyPackages.x86_64-linux.libdbusmenu-gtk3 ]; - }); - isync = prev.isync.overrideAttrs (old: { - withCyrusSaslXoauth2 = true; - }); - blender = prev.blender.overrideAttrs (old: { - nativeBuildInputs = (old.nativeBuildInputs or []) ++ [ inputs.nixpkgs.legacyPackages.x86_64-linux.pkg-config inputs.nixpkgs.legacyPackages.x86_64-linux.wayland-scanner ]; + buildInputs = old.buildInputs + ++ [ inputs.nixpkgs.legacyPackages.x86_64-linux.libdbusmenu-gtk3 ]; }); + isync = prev.isync.overrideAttrs (old: { withCyrusSaslXoauth2 = true; }); }; # incase something breaks diff --git a/secrets/secrets.nix b/secrets/secrets.nix new file mode 100644 index 00000000..72b73147 --- /dev/null +++ b/secrets/secrets.nix @@ -0,0 +1,12 @@ +let + sakotop = + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPGAwG2Fqs3xNF/6/9GdznH/jUIqxW3aTYvmteuq9odZ sako@sakotop"; + sakopc = + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDjPSt4TykAJgafU9Trk7sr9wzXhBZxawDIZir0CPyDN sako@sakopc"; + + shared = [ sakotop sakopc ]; + +in { + "test.age".publicKeys = shared; + "shared/torrc.age".publicKeys = shared; +} diff --git a/secrets/shared/torrc.age b/secrets/shared/torrc.age new file mode 100644 index 00000000..58192787 Binary files /dev/null and b/secrets/shared/torrc.age differ diff --git a/secrets/test.age b/secrets/test.age new file mode 100644 index 00000000..4858f02b Binary files /dev/null and b/secrets/test.age differ