From 83100caf745b0844dadab5f2e87381394f8a58f5 Mon Sep 17 00:00:00 2001 From: horhik Date: Mon, 31 May 2021 15:42:36 +0300 Subject: [PATCH] some updtaes --- .gitignore | 4 + dmenu-4.9/LICENSE | 30 - dmenu-4.9/Makefile | 64 - dmenu-4.9/README | 24 - dmenu-4.9/arg.h | 49 - dmenu-4.9/border.diff | 25 - dmenu-4.9/center.diff | 120 - dmenu-4.9/config.def.h | 31 - dmenu-4.9/config.def.h.orig | 29 - dmenu-4.9/config.def.h.rej | 9 - dmenu-4.9/config.h | 31 - dmenu-4.9/config.mk | 31 - dmenu-4.9/dmenu | Bin 44120 -> 0 bytes dmenu-4.9/dmenu.1 | 222 -- dmenu-4.9/dmenu.1.orig | 202 -- dmenu-4.9/dmenu.c | 855 ------ dmenu-4.9/dmenu.c.orig | 802 ----- dmenu-4.9/dmenu.c.rej | 14 - dmenu-4.9/dmenu_path | 13 - dmenu-4.9/dmenu_run | 2 - dmenu-4.9/drw.c | 430 --- dmenu-4.9/drw.h | 57 - dmenu-4.9/fuzzyhighlight.diff | 152 - dmenu-4.9/grid.diff | 107 - dmenu-4.9/stest | Bin 17744 -> 0 bytes dmenu-4.9/stest.1 | 90 - dmenu-4.9/stest.c | 109 - dmenu-4.9/util.c | 35 - dmenu-4.9/util.h | 8 - dwm-6.2/LICENSE | 37 - dwm-6.2/Makefile | 51 - dwm-6.2/README | 48 - dwm-6.2/config.def.h | 201 -- dwm-6.2/config.def.h.orig | 177 -- dwm-6.2/config.def.h.rej | 18 - dwm-6.2/config.h | 201 -- dwm-6.2/config.mk | 38 - dwm-6.2/drw.c | 433 --- dwm-6.2/drw.h | 57 - dwm-6.2/dwm | Bin 77528 -> 0 bytes dwm-6.2/dwm.1 | 199 -- dwm-6.2/dwm.c | 2515 ---------------- dwm-6.2/dwm.c.orig | 2404 --------------- dwm-6.2/dwm.c.rej | 88 - dwm-6.2/dwm.png | Bin 373 -> 0 bytes ...dwm-actualfullscreen-20191112-cb3f58a.diff | 53 - dwm-6.2/patches/dwm-alternativetags-6.2.diff | 93 - .../dwm-alwayscenter-20200625-f04cac6.diff | 12 - .../dwm-autostart-20161205-bb3bd6f.diff | 39 - .../dwm-autostart-20200610-cb3f58a.diff | 179 -- ...m-centeredwindowname-20200723-f035e1e.diff | 30 - dwm-6.2/patches/dwm-cool-autostart-6.2.diff | 116 - .../dwm-fakefullscreen-20170508-ceac8c9.diff | 92 - dwm-6.2/patches/dwm-floatrules-6.2.diff | 64 - dwm-6.2/patches/dwm-fullscreen-6.2.diff | 56 - dwm-6.2/patches/dwm-gaps-6.0.diff | 53 - .../dwm-launchers-20200527-f09418b.diff | 101 - dwm-6.2/patches/dwm-namedscratchpads-6.2.diff | 138 - dwm-6.2/patches/dwm-noborder-6.2.diff | 30 - dwm-6.2/patches/dwm-ru_gaps-6.2.diff | 127 - dwm-6.2/patches/dwm-smartborders-6.2.diff | 225 -- .../patches/dwm-vanitygaps-20190508-6.2.diff | 259 -- .../dwm-vanitygaps-20200610-f09418b.diff | 262 -- dwm-6.2/patches/patches.txt | 8 - dwm-6.2/patches/wm-colorbar-6.2.diff | 68 - dwm-6.2/transient.c | 42 - dwm-6.2/util.c | 35 - dwm-6.2/util.h | 8 - home/gtk/.config/gtk-2.0/gtkfilechooser.ini | 8 +- home/picom/.config/picom/picom.conf. | 34 + home/picom/.config/picom/picom.conf_ | 414 --- .../.config/picom/{picom.conf => picom.conff} | 68 +- home/pure_emacs/.emacs.d/config.org | 98 +- home/pure_emacs/.emacs.d/init.el | 43 +- home/scripts/.local/scripts/status/statusbar | 2 +- home/vim/.config/nvim/.netrwhist | 4 + home/xmonad/.config/xmobar/bin/a | 0 home/xmonad/.config/xmobar/bin/xmobarstatus | 2 +- home/xmonad/.config/xmobar/bin/xmobarstatus2 | 2 +- home/xmonad/.config/xmobar/config.hs | 2 +- home/xmonad/.config/xmobar/config_second.hs | 2 +- home/xmonad/.xmonad/lib/GruvboxColors.hi | Bin 1573 -> 1569 bytes home/xmonad/.xmonad/xmonad.hs | 17 +- home/zsh/.zshrc | 109 +- info.txt | 2 - install | 25 - install.sh | 2 +- my_dwm/LICENSE | 37 - my_dwm/Makefile | 51 - my_dwm/README | 48 - my_dwm/config.def.h | 152 - my_dwm/config.h | 152 - my_dwm/config.mk | 38 - my_dwm/drw.c | 438 --- my_dwm/drw.h | 57 - my_dwm/dwm | Bin 71360 -> 0 bytes my_dwm/dwm.1 | 176 -- my_dwm/dwm.c | 2288 --------------- my_dwm/dwm.png | Bin 373 -> 0 bytes .../dwm-autostart-20161205-bb3bd6f.diff | 39 - .../dwm-autostart-20200610-cb3f58a.diff | 179 -- my_dwm/patches/dwm-cool-autostart-6.2.diff | 116 - .../dwm-fakefullscreen-20170508-ceac8c9.diff | 92 - my_dwm/patches/dwm-floatrules-6.2.diff | 64 - my_dwm/patches/dwm-gaps-6.0.diff | 53 - .../dwm-launchers-20200527-f09418b.diff | 101 - my_dwm/patches/dwm-namedscratchpads-6.2.diff | 138 - my_dwm/patches/dwm-ru_gaps-6.2.diff | 127 - .../dwm-vanitygaps-20200610-f09418b.diff | 262 -- my_dwm/transient.c | 42 - my_dwm/util.c | 35 - my_dwm/util.h | 8 - packages.txt | 1 - problems.md | 6 - st/FAQ | 250 -- st/LEGACY | 17 - st/LICENSE | 34 - st/Makefile | 57 - st/README | 34 - st/TODO | 28 - st/arg.h | 50 - st/config.def.h | 468 --- st/config.def.h.orig | 466 --- st/config.def.h.rej | 10 - st/config.h | 468 --- st/config.mk | 35 - st/patches/st-font2-20190326-f64c2f8.diff | 126 - st/patches/st-gruvbox-dark-0.8.2.diff | 70 - st/st | Bin 104904 -> 0 bytes st/st.1 | 177 -- st/st.c | 2605 ----------------- st/st.h | 125 - st/st.info | 239 -- st/win.h | 40 - st/x.c | 2136 -------------- st/x.c.orig | 2063 ------------- time.sh | 7 - image-links.txt => wallpapers.txt | 0 138 files changed, 205 insertions(+), 26936 deletions(-) delete mode 100644 dmenu-4.9/LICENSE delete mode 100644 dmenu-4.9/Makefile delete mode 100644 dmenu-4.9/README delete mode 100644 dmenu-4.9/arg.h delete mode 100644 dmenu-4.9/border.diff delete mode 100644 dmenu-4.9/center.diff delete mode 100644 dmenu-4.9/config.def.h delete mode 100644 dmenu-4.9/config.def.h.orig delete mode 100644 dmenu-4.9/config.def.h.rej delete mode 100644 dmenu-4.9/config.h delete mode 100644 dmenu-4.9/config.mk delete mode 100755 dmenu-4.9/dmenu delete mode 100644 dmenu-4.9/dmenu.1 delete mode 100644 dmenu-4.9/dmenu.1.orig delete mode 100644 dmenu-4.9/dmenu.c delete mode 100644 dmenu-4.9/dmenu.c.orig delete mode 100644 dmenu-4.9/dmenu.c.rej delete mode 100644 dmenu-4.9/dmenu_path delete mode 100755 dmenu-4.9/dmenu_run delete mode 100644 dmenu-4.9/drw.c delete mode 100644 dmenu-4.9/drw.h delete mode 100644 dmenu-4.9/fuzzyhighlight.diff delete mode 100644 dmenu-4.9/grid.diff delete mode 100755 dmenu-4.9/stest delete mode 100644 dmenu-4.9/stest.1 delete mode 100644 dmenu-4.9/stest.c delete mode 100644 dmenu-4.9/util.c delete mode 100644 dmenu-4.9/util.h delete mode 100644 dwm-6.2/LICENSE delete mode 100644 dwm-6.2/Makefile delete mode 100644 dwm-6.2/README delete mode 100644 dwm-6.2/config.def.h delete mode 100644 dwm-6.2/config.def.h.orig delete mode 100644 dwm-6.2/config.def.h.rej delete mode 100644 dwm-6.2/config.h delete mode 100644 dwm-6.2/config.mk delete mode 100644 dwm-6.2/drw.c delete mode 100644 dwm-6.2/drw.h delete mode 100755 dwm-6.2/dwm delete mode 100644 dwm-6.2/dwm.1 delete mode 100644 dwm-6.2/dwm.c delete mode 100644 dwm-6.2/dwm.c.orig delete mode 100644 dwm-6.2/dwm.c.rej delete mode 100644 dwm-6.2/dwm.png delete mode 100644 dwm-6.2/patches/dwm-actualfullscreen-20191112-cb3f58a.diff delete mode 100644 dwm-6.2/patches/dwm-alternativetags-6.2.diff delete mode 100644 dwm-6.2/patches/dwm-alwayscenter-20200625-f04cac6.diff delete mode 100644 dwm-6.2/patches/dwm-autostart-20161205-bb3bd6f.diff delete mode 100644 dwm-6.2/patches/dwm-autostart-20200610-cb3f58a.diff delete mode 100644 dwm-6.2/patches/dwm-centeredwindowname-20200723-f035e1e.diff delete mode 100644 dwm-6.2/patches/dwm-cool-autostart-6.2.diff delete mode 100644 dwm-6.2/patches/dwm-fakefullscreen-20170508-ceac8c9.diff delete mode 100644 dwm-6.2/patches/dwm-floatrules-6.2.diff delete mode 100644 dwm-6.2/patches/dwm-fullscreen-6.2.diff delete mode 100644 dwm-6.2/patches/dwm-gaps-6.0.diff delete mode 100644 dwm-6.2/patches/dwm-launchers-20200527-f09418b.diff delete mode 100644 dwm-6.2/patches/dwm-namedscratchpads-6.2.diff delete mode 100644 dwm-6.2/patches/dwm-noborder-6.2.diff delete mode 100644 dwm-6.2/patches/dwm-ru_gaps-6.2.diff delete mode 100644 dwm-6.2/patches/dwm-smartborders-6.2.diff delete mode 100644 dwm-6.2/patches/dwm-vanitygaps-20190508-6.2.diff delete mode 100644 dwm-6.2/patches/dwm-vanitygaps-20200610-f09418b.diff delete mode 100644 dwm-6.2/patches/patches.txt delete mode 100644 dwm-6.2/patches/wm-colorbar-6.2.diff delete mode 100644 dwm-6.2/transient.c delete mode 100644 dwm-6.2/util.c delete mode 100644 dwm-6.2/util.h create mode 100644 home/picom/.config/picom/picom.conf. delete mode 100644 home/picom/.config/picom/picom.conf_ rename home/picom/.config/picom/{picom.conf => picom.conff} (74%) create mode 100644 home/vim/.config/nvim/.netrwhist mode change 100644 => 100755 home/xmonad/.config/xmobar/bin/a delete mode 100644 info.txt delete mode 100755 install delete mode 100644 my_dwm/LICENSE delete mode 100644 my_dwm/Makefile delete mode 100644 my_dwm/README delete mode 100644 my_dwm/config.def.h delete mode 100644 my_dwm/config.h delete mode 100644 my_dwm/config.mk delete mode 100644 my_dwm/drw.c delete mode 100644 my_dwm/drw.h delete mode 100755 my_dwm/dwm delete mode 100644 my_dwm/dwm.1 delete mode 100644 my_dwm/dwm.c delete mode 100644 my_dwm/dwm.png delete mode 100644 my_dwm/patches/dwm-autostart-20161205-bb3bd6f.diff delete mode 100644 my_dwm/patches/dwm-autostart-20200610-cb3f58a.diff delete mode 100644 my_dwm/patches/dwm-cool-autostart-6.2.diff delete mode 100644 my_dwm/patches/dwm-fakefullscreen-20170508-ceac8c9.diff delete mode 100644 my_dwm/patches/dwm-floatrules-6.2.diff delete mode 100644 my_dwm/patches/dwm-gaps-6.0.diff delete mode 100644 my_dwm/patches/dwm-launchers-20200527-f09418b.diff delete mode 100644 my_dwm/patches/dwm-namedscratchpads-6.2.diff delete mode 100644 my_dwm/patches/dwm-ru_gaps-6.2.diff delete mode 100644 my_dwm/patches/dwm-vanitygaps-20200610-f09418b.diff delete mode 100644 my_dwm/transient.c delete mode 100644 my_dwm/util.c delete mode 100644 my_dwm/util.h delete mode 100644 packages.txt delete mode 100644 problems.md delete mode 100644 st/FAQ delete mode 100644 st/LEGACY delete mode 100644 st/LICENSE delete mode 100644 st/Makefile delete mode 100644 st/README delete mode 100644 st/TODO delete mode 100644 st/arg.h delete mode 100644 st/config.def.h delete mode 100644 st/config.def.h.orig delete mode 100644 st/config.def.h.rej delete mode 100644 st/config.h delete mode 100644 st/config.mk delete mode 100644 st/patches/st-font2-20190326-f64c2f8.diff delete mode 100644 st/patches/st-gruvbox-dark-0.8.2.diff delete mode 100755 st/st delete mode 100644 st/st.1 delete mode 100644 st/st.c delete mode 100644 st/st.h delete mode 100644 st/st.info delete mode 100644 st/win.h delete mode 100644 st/x.c delete mode 100644 st/x.c.orig delete mode 100755 time.sh rename image-links.txt => wallpapers.txt (100%) diff --git a/.gitignore b/.gitignore index 23799da..a8cf933 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,10 @@ home/tmux/.config/tmux/plugins/ *.o *~ +*.db +*.db.lock +*# +*~ home/pure_emacs/.emacs.d/.cache/ home/pure_emacs/.emacs.d/elpa/ home/pure_emacs/.emacs.d/org-roam.db diff --git a/dmenu-4.9/LICENSE b/dmenu-4.9/LICENSE deleted file mode 100644 index 6ed8ad3..0000000 --- a/dmenu-4.9/LICENSE +++ /dev/null @@ -1,30 +0,0 @@ -MIT/X Consortium License - -© 2006-2019 Anselm R Garbe -© 2006-2008 Sander van Dijk -© 2006-2007 Michał Janeczek -© 2007 Kris Maglione -© 2009 Gottox -© 2009 Markus Schnalke -© 2009 Evan Gates -© 2010-2012 Connor Lane Smith -© 2014-2019 Hiltjo Posthuma -© 2015-2018 Quentin Rameau - -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/dmenu-4.9/Makefile b/dmenu-4.9/Makefile deleted file mode 100644 index a03a95c..0000000 --- a/dmenu-4.9/Makefile +++ /dev/null @@ -1,64 +0,0 @@ -# dmenu - dynamic menu -# See LICENSE file for copyright and license details. - -include config.mk - -SRC = drw.c dmenu.c stest.c util.c -OBJ = $(SRC:.c=.o) - -all: options dmenu stest - -options: - @echo dmenu build options: - @echo "CFLAGS = $(CFLAGS)" - @echo "LDFLAGS = $(LDFLAGS)" - @echo "CC = $(CC)" - -.c.o: - $(CC) -c $(CFLAGS) $< - -config.h: - cp config.def.h $@ - -$(OBJ): arg.h config.h config.mk drw.h - -dmenu: dmenu.o drw.o util.o - $(CC) -o $@ dmenu.o drw.o util.o $(LDFLAGS) - -stest: stest.o - $(CC) -o $@ stest.o $(LDFLAGS) - -clean: - rm -f dmenu stest $(OBJ) dmenu-$(VERSION).tar.gz - -dist: clean - mkdir -p dmenu-$(VERSION) - cp LICENSE Makefile README arg.h config.def.h config.mk dmenu.1\ - drw.h util.h dmenu_path dmenu_run stest.1 $(SRC)\ - dmenu-$(VERSION) - tar -cf dmenu-$(VERSION).tar dmenu-$(VERSION) - gzip dmenu-$(VERSION).tar - rm -rf dmenu-$(VERSION) - -install: all - mkdir -p $(DESTDIR)$(PREFIX)/bin - cp -f dmenu dmenu_path dmenu_run stest $(DESTDIR)$(PREFIX)/bin - chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu - chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_path - chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_run - chmod 755 $(DESTDIR)$(PREFIX)/bin/stest - mkdir -p $(DESTDIR)$(MANPREFIX)/man1 - sed "s/VERSION/$(VERSION)/g" < dmenu.1 > $(DESTDIR)$(MANPREFIX)/man1/dmenu.1 - sed "s/VERSION/$(VERSION)/g" < stest.1 > $(DESTDIR)$(MANPREFIX)/man1/stest.1 - chmod 644 $(DESTDIR)$(MANPREFIX)/man1/dmenu.1 - chmod 644 $(DESTDIR)$(MANPREFIX)/man1/stest.1 - -uninstall: - rm -f $(DESTDIR)$(PREFIX)/bin/dmenu\ - $(DESTDIR)$(PREFIX)/bin/dmenu_path\ - $(DESTDIR)$(PREFIX)/bin/dmenu_run\ - $(DESTDIR)$(PREFIX)/bin/stest\ - $(DESTDIR)$(MANPREFIX)/man1/dmenu.1\ - $(DESTDIR)$(MANPREFIX)/man1/stest.1 - -.PHONY: all options clean dist install uninstall diff --git a/dmenu-4.9/README b/dmenu-4.9/README deleted file mode 100644 index a8fcdfe..0000000 --- a/dmenu-4.9/README +++ /dev/null @@ -1,24 +0,0 @@ -dmenu - dynamic menu -==================== -dmenu is an efficient dynamic menu for X. - - -Requirements ------------- -In order to build dmenu you need the Xlib header files. - - -Installation ------------- -Edit config.mk to match your local setup (dmenu is installed into -the /usr/local namespace by default). - -Afterwards enter the following command to build and install dmenu -(if necessary as root): - - make clean install - - -Running dmenu -------------- -See the man page for details. diff --git a/dmenu-4.9/arg.h b/dmenu-4.9/arg.h deleted file mode 100644 index e94e02b..0000000 --- a/dmenu-4.9/arg.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copy me if you can. - * by 20h - */ - -#ifndef ARG_H__ -#define ARG_H__ - -extern char *argv0; - -/* use main(int argc, char *argv[]) */ -#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ - argv[0] && argv[0][0] == '-'\ - && argv[0][1];\ - argc--, argv++) {\ - char argc_;\ - char **argv_;\ - int brk_;\ - if (argv[0][1] == '-' && argv[0][2] == '\0') {\ - argv++;\ - argc--;\ - break;\ - }\ - for (brk_ = 0, argv[0]++, argv_ = argv;\ - argv[0][0] && !brk_;\ - argv[0]++) {\ - if (argv_ != argv)\ - break;\ - argc_ = argv[0][0];\ - switch (argc_) - -#define ARGEND }\ - } - -#define ARGC() argc_ - -#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\ - ((x), abort(), (char *)0) :\ - (brk_ = 1, (argv[0][1] != '\0')?\ - (&argv[0][1]) :\ - (argc--, argv++, argv[0]))) - -#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\ - (char *)0 :\ - (brk_ = 1, (argv[0][1] != '\0')?\ - (&argv[0][1]) :\ - (argc--, argv++, argv[0]))) - -#endif diff --git a/dmenu-4.9/border.diff b/dmenu-4.9/border.diff deleted file mode 100644 index 89b4437..0000000 --- a/dmenu-4.9/border.diff +++ /dev/null @@ -1,25 +0,0 @@ -diff -up dmenu-4.9-b/config.def.h dmenu-4.9-a/config.def.h ---- dmenu-4.9-b/config.def.h 2019-02-02 13:55:02.000000000 +0100 -+++ dmenu-4.9-a/config.def.h 2019-05-19 02:10:12.740040403 +0200 -@@ -21,3 +21,6 @@ static unsigned int lines = 0; - * for example: " /?\"&[]" - */ - static const char worddelimiters[] = " "; -+ -+/* Size of the window border */ -+static const unsigned int border_width = 5; -diff -up dmenu-4.9-b/dmenu.c dmenu-4.9-a/dmenu.c ---- dmenu-4.9-b/dmenu.c 2019-02-02 13:55:02.000000000 +0100 -+++ dmenu-4.9-a/dmenu.c 2019-05-19 02:11:20.966710117 +0200 -@@ -654,9 +654,10 @@ setup(void) - swa.override_redirect = True; - swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; - swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; -- win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0, -+ win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width, - CopyFromParent, CopyFromParent, CopyFromParent, - CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); -+ XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel); - XSetClassHint(dpy, win, &ch); - - /* open input methods */ diff --git a/dmenu-4.9/center.diff b/dmenu-4.9/center.diff deleted file mode 100644 index af249a6..0000000 --- a/dmenu-4.9/center.diff +++ /dev/null @@ -1,120 +0,0 @@ -From 8cd37e1ab9e7cb025224aeb3543f1a5be8bceb93 Mon Sep 17 00:00:00 2001 -From: Nihal Jere -Date: Sat, 11 Jan 2020 21:16:08 -0600 -Subject: [PATCH] center patch now has adjustable minimum width - ---- - config.def.h | 2 ++ - dmenu.1 | 3 +++ - dmenu.c | 39 ++++++++++++++++++++++++++++++++------- - 3 files changed, 37 insertions(+), 7 deletions(-) - -diff --git a/config.def.h b/config.def.h -index 1edb647..88ef264 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -2,6 +2,8 @@ - /* Default settings; can be overriden by command line. */ - - static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ -+static int centered = 0; /* -c option; centers dmenu on screen */ -+static int min_width = 500; /* minimum width when centered */ - /* -fn option overrides fonts[0]; default X11 font or font set */ - static const char *fonts[] = { - "monospace:size=10" -diff --git a/dmenu.1 b/dmenu.1 -index 323f93c..c036baa 100644 ---- a/dmenu.1 -+++ b/dmenu.1 -@@ -40,6 +40,9 @@ which lists programs in the user's $PATH and runs the result in their $SHELL. - .B \-b - dmenu appears at the bottom of the screen. - .TP -+.B \-c -+dmenu appears centered on the screen. -+.TP - .B \-f - dmenu grabs the keyboard before reading stdin if not reading from a tty. This - is faster, but will lock up X until stdin reaches end\-of\-file. -diff --git a/dmenu.c b/dmenu.c -index 65f25ce..041c7f8 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -89,6 +89,15 @@ calcoffsets(void) - break; - } - -+static int -+max_textw(void) -+{ -+ int len = 0; -+ for (struct item *item = items; item && item->text; item++) -+ len = MAX(TEXTW(item->text), len); -+ return len; -+} -+ - static void - cleanup(void) - { -@@ -611,6 +620,7 @@ setup(void) - bh = drw->fonts->h + 2; - lines = MAX(lines, 0); - mh = (lines + 1) * bh; -+ promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; - #ifdef XINERAMA - i = 0; - if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { -@@ -637,9 +647,16 @@ setup(void) - if (INTERSECT(x, y, 1, 1, info[i])) - break; - -- x = info[i].x_org; -- y = info[i].y_org + (topbar ? 0 : info[i].height - mh); -- mw = info[i].width; -+ if (centered) { -+ mw = MIN(MAX(max_textw() + promptw, min_width), info[i].width); -+ x = info[i].x_org + ((info[i].width - mw) / 2); -+ y = info[i].y_org + ((info[i].height - mh) / 2); -+ } else { -+ x = info[i].x_org; -+ y = info[i].y_org + (topbar ? 0 : info[i].height - mh); -+ mw = info[i].width; -+ } -+ - XFree(info); - } else - #endif -@@ -647,11 +664,17 @@ setup(void) - if (!XGetWindowAttributes(dpy, parentwin, &wa)) - die("could not get embedding window attributes: 0x%lx", - parentwin); -- x = 0; -- y = topbar ? 0 : wa.height - mh; -- mw = wa.width; -+ -+ if (centered) { -+ mw = MIN(MAX(max_textw() + promptw, min_width), wa.width); -+ x = (wa.width - mw) / 2; -+ y = (wa.height - mh) / 2; -+ } else { -+ x = 0; -+ y = topbar ? 0 : wa.height - mh; -+ mw = wa.width; -+ } - } -- promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; - inputw = MIN(inputw, mw/3); - match(); - -@@ -709,6 +732,8 @@ main(int argc, char *argv[]) - topbar = 0; - else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ - fast = 1; -+ else if (!strcmp(argv[i], "-c")) /* centers dmenu on screen */ -+ centered = 1; - else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ - fstrncmp = strncasecmp; - fstrstr = cistrstr; --- -2.24.1 - diff --git a/dmenu-4.9/config.def.h b/dmenu-4.9/config.def.h deleted file mode 100644 index 7ab1de5..0000000 --- a/dmenu-4.9/config.def.h +++ /dev/null @@ -1,31 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -/* Default settings; can be overriden by command line. */ - -static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ -static int centered = 0; /* -c option; centers dmenu on screen */ -static int min_width = 500; /* minimum width when centered */ -/* -fn option overrides fonts[0]; default X11 font or font set */ -static const char *fonts[] = { - "monospace:size=10" -}; -static const char *prompt = NULL; /* -p option; prompt to the left of input field */ -static const char *colors[SchemeLast][2] = { - /* fg bg */ - [SchemeNorm] = { "#44475a", "#282a36" }, - [SchemeSel] = { "#eeeeee", "#005577" }, - [SchemeSelHighlight] = { "#ffc978", "#005577" }, - [SchemeNormHighlight] = { "#ffc978", "#222222" }, - [SchemeOut] = { "#000000", "#00ffff" }, -}; -/* -l and -g options; controls number of lines and columns in grid if > 0 */ -static unsigned int lines = 0; -static unsigned int columns = 0; - -/* - * Characters not considered part of a word while deleting words - * for example: " /?\"&[]" - */ -static const char worddelimiters[] = " "; - -/* Size of the window border */ -static const unsigned int border_width = 5; diff --git a/dmenu-4.9/config.def.h.orig b/dmenu-4.9/config.def.h.orig deleted file mode 100644 index 6f248d0..0000000 --- a/dmenu-4.9/config.def.h.orig +++ /dev/null @@ -1,29 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -/* Default settings; can be overriden by command line. */ - -static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ -static int centered = 0; /* -c option; centers dmenu on screen */ -static int min_width = 500; /* minimum width when centered */ -/* -fn option overrides fonts[0]; default X11 font or font set */ -static const char *fonts[] = { - "monospace:size=10" -}; -static const char *prompt = NULL; /* -p option; prompt to the left of input field */ -static const char *colors[SchemeLast][2] = { - /* fg bg */ - [SchemeNorm] = { "#bbbbbb", "#222222" }, - [SchemeSel] = { "#eeeeee", "#005577" }, - [SchemeOut] = { "#000000", "#00ffff" }, -}; -/* -l and -g options; controls number of lines and columns in grid if > 0 */ -static unsigned int lines = 0; -static unsigned int columns = 0; - -/* - * Characters not considered part of a word while deleting words - * for example: " /?\"&[]" - */ -static const char worddelimiters[] = " "; - -/* Size of the window border */ -static const unsigned int border_width = 5; diff --git a/dmenu-4.9/config.def.h.rej b/dmenu-4.9/config.def.h.rej deleted file mode 100644 index 1875e56..0000000 --- a/dmenu-4.9/config.def.h.rej +++ /dev/null @@ -1,9 +0,0 @@ ---- config.def.h 2019-02-02 13:55:02.000000000 +0100 -+++ config.def.h 2019-05-19 02:10:12.740040403 +0200 -@@ -21,3 +21,6 @@ static unsigned int lines = 0; - * for example: " /?\"&[]" - */ - static const char worddelimiters[] = " "; -+ -+/* Size of the window border */ -+static const unsigned int border_width = 5; diff --git a/dmenu-4.9/config.h b/dmenu-4.9/config.h deleted file mode 100644 index 7ab1de5..0000000 --- a/dmenu-4.9/config.h +++ /dev/null @@ -1,31 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -/* Default settings; can be overriden by command line. */ - -static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */ -static int centered = 0; /* -c option; centers dmenu on screen */ -static int min_width = 500; /* minimum width when centered */ -/* -fn option overrides fonts[0]; default X11 font or font set */ -static const char *fonts[] = { - "monospace:size=10" -}; -static const char *prompt = NULL; /* -p option; prompt to the left of input field */ -static const char *colors[SchemeLast][2] = { - /* fg bg */ - [SchemeNorm] = { "#44475a", "#282a36" }, - [SchemeSel] = { "#eeeeee", "#005577" }, - [SchemeSelHighlight] = { "#ffc978", "#005577" }, - [SchemeNormHighlight] = { "#ffc978", "#222222" }, - [SchemeOut] = { "#000000", "#00ffff" }, -}; -/* -l and -g options; controls number of lines and columns in grid if > 0 */ -static unsigned int lines = 0; -static unsigned int columns = 0; - -/* - * Characters not considered part of a word while deleting words - * for example: " /?\"&[]" - */ -static const char worddelimiters[] = " "; - -/* Size of the window border */ -static const unsigned int border_width = 5; diff --git a/dmenu-4.9/config.mk b/dmenu-4.9/config.mk deleted file mode 100644 index 0929b4a..0000000 --- a/dmenu-4.9/config.mk +++ /dev/null @@ -1,31 +0,0 @@ -# dmenu version -VERSION = 4.9 - -# 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 - -# 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=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS) -CFLAGS = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS) -LDFLAGS = $(LIBS) - -# compiler and linker -CC = cc diff --git a/dmenu-4.9/dmenu b/dmenu-4.9/dmenu deleted file mode 100755 index bf00503f9283c74831502613c621b4e7fb35edb4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44120 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 diff --git a/dmenu-4.9/dmenu.1 b/dmenu-4.9/dmenu.1 deleted file mode 100644 index f6ae948..0000000 --- a/dmenu-4.9/dmenu.1 +++ /dev/null @@ -1,222 +0,0 @@ -.TH DMENU 1 dmenu\-VERSION -.SH NAME -dmenu \- dynamic menu -.SH SYNOPSIS -.B dmenu -.RB [ \-bfiv ] -.RB [ \-g -.IR columns ] -.RB [ \-l -.IR lines ] -.RB [ \-m -.IR monitor ] -.RB [ \-p -.IR prompt ] -.RB [ \-fn -.IR font ] -.RB [ \-nb -.IR color ] -.RB [ \-nf -.IR color ] -.RB [ \-sb -.IR color ] -.RB [ \-sf -.IR color ] -.RB [ \-nhb -.IR color ] -.RB [ \-nhf -.IR color ] -.RB [ \-shb -.IR color ] -.RB [ \-shf -.IR color ] -.RB [ \-w -.IR windowid ] -.P -.BR dmenu_run " ..." -.SH DESCRIPTION -.B dmenu -is a dynamic menu for X, which reads a list of newline\-separated items from -stdin. When the user selects an item and presses Return, their choice is printed -to stdout and dmenu terminates. Entering text will narrow the items to those -matching the tokens in the input. -.P -.B dmenu_run -is a script used by -.IR dwm (1) -which lists programs in the user's $PATH and runs the result in their $SHELL. -.SH OPTIONS -.TP -.B \-b -dmenu appears at the bottom of the screen. -.TP -.B \-c -dmenu appears centered on the screen. -.TP -.B \-f -dmenu grabs the keyboard before reading stdin if not reading from a tty. This -is faster, but will lock up X until stdin reaches end\-of\-file. -.TP -.B \-i -dmenu matches menu items case insensitively. -.TP -.BI \-g " columns" -dmenu lists items in a grid with the given number of columns. -.TP -.BI \-l " lines" -dmenu lists items in a grid with the given number of lines. -.TP -.BI \-m " monitor" -dmenu is displayed on the monitor number supplied. Monitor numbers are starting -from 0. -.TP -.BI \-p " prompt" -defines the prompt to be displayed to the left of the input field. -.TP -.BI \-fn " font" -defines the font or font set used. -.TP -.BI \-nb " color" -defines the normal background color. -.IR #RGB , -.IR #RRGGBB , -and X color names are supported. -.TP -.BI \-nf " color" -defines the normal foreground color. -.TP -.BI \-sb " color" -defines the selected background color. -.TP -.BI \-sf " color" -defines the selected foreground color. -.TP -.BI \-nhb " color" -defines the normal highlight background color. -.TP -.BI \-nhf " color" -defines the normal highlight foreground color. -.TP -.BI \-shb " color" -defines the selected highlight background color. -.TP -.BI \-shf " color" -defines the selected highlight foreground color. -.TP -.B \-v -prints version information to stdout, then exits. -.TP -.BI \-w " windowid" -embed into windowid. -.SH USAGE -dmenu is completely controlled by the keyboard. Items are selected using the -arrow keys, page up, page down, home, and end. -.TP -.B Tab -Copy the selected item to the input field. -.TP -.B Return -Confirm selection. Prints the selected item to stdout and exits, returning -success. -.TP -.B Ctrl-Return -Confirm selection. Prints the selected item to stdout and continues. -.TP -.B Shift\-Return -Confirm input. Prints the input text to stdout and exits, returning success. -.TP -.B Escape -Exit without selecting an item, returning failure. -.TP -.B Ctrl-Left -Move cursor to the start of the current word -.TP -.B Ctrl-Right -Move cursor to the end of the current word -.TP -.B C\-a -Home -.TP -.B C\-b -Left -.TP -.B C\-c -Escape -.TP -.B C\-d -Delete -.TP -.B C\-e -End -.TP -.B C\-f -Right -.TP -.B C\-g -Escape -.TP -.B C\-h -Backspace -.TP -.B C\-i -Tab -.TP -.B C\-j -Return -.TP -.B C\-J -Shift-Return -.TP -.B C\-k -Delete line right -.TP -.B C\-m -Return -.TP -.B C\-M -Shift-Return -.TP -.B C\-n -Down -.TP -.B C\-p -Up -.TP -.B C\-u -Delete line left -.TP -.B C\-w -Delete word left -.TP -.B C\-y -Paste from primary X selection -.TP -.B C\-Y -Paste from X clipboard -.TP -.B M\-b -Move cursor to the start of the current word -.TP -.B M\-f -Move cursor to the end of the current word -.TP -.B M\-g -Home -.TP -.B M\-G -End -.TP -.B M\-h -Up -.TP -.B M\-j -Page down -.TP -.B M\-k -Page up -.TP -.B M\-l -Down -.SH SEE ALSO -.IR dwm (1), -.IR stest (1) diff --git a/dmenu-4.9/dmenu.1.orig b/dmenu-4.9/dmenu.1.orig deleted file mode 100644 index 57ea184..0000000 --- a/dmenu-4.9/dmenu.1.orig +++ /dev/null @@ -1,202 +0,0 @@ -.TH DMENU 1 dmenu\-VERSION -.SH NAME -dmenu \- dynamic menu -.SH SYNOPSIS -.B dmenu -.RB [ \-bfiv ] -.RB [ \-g -.IR columns ] -.RB [ \-l -.IR lines ] -.RB [ \-m -.IR monitor ] -.RB [ \-p -.IR prompt ] -.RB [ \-fn -.IR font ] -.RB [ \-nb -.IR color ] -.RB [ \-nf -.IR color ] -.RB [ \-sb -.IR color ] -.RB [ \-sf -.IR color ] -.RB [ \-w -.IR windowid ] -.P -.BR dmenu_run " ..." -.SH DESCRIPTION -.B dmenu -is a dynamic menu for X, which reads a list of newline\-separated items from -stdin. When the user selects an item and presses Return, their choice is printed -to stdout and dmenu terminates. Entering text will narrow the items to those -matching the tokens in the input. -.P -.B dmenu_run -is a script used by -.IR dwm (1) -which lists programs in the user's $PATH and runs the result in their $SHELL. -.SH OPTIONS -.TP -.B \-b -dmenu appears at the bottom of the screen. -.TP -.B \-c -dmenu appears centered on the screen. -.TP -.B \-f -dmenu grabs the keyboard before reading stdin if not reading from a tty. This -is faster, but will lock up X until stdin reaches end\-of\-file. -.TP -.B \-i -dmenu matches menu items case insensitively. -.TP -.BI \-g " columns" -dmenu lists items in a grid with the given number of columns. -.TP -.BI \-l " lines" -dmenu lists items in a grid with the given number of lines. -.TP -.BI \-m " monitor" -dmenu is displayed on the monitor number supplied. Monitor numbers are starting -from 0. -.TP -.BI \-p " prompt" -defines the prompt to be displayed to the left of the input field. -.TP -.BI \-fn " font" -defines the font or font set used. -.TP -.BI \-nb " color" -defines the normal background color. -.IR #RGB , -.IR #RRGGBB , -and X color names are supported. -.TP -.BI \-nf " color" -defines the normal foreground color. -.TP -.BI \-sb " color" -defines the selected background color. -.TP -.BI \-sf " color" -defines the selected foreground color. -.TP -.B \-v -prints version information to stdout, then exits. -.TP -.BI \-w " windowid" -embed into windowid. -.SH USAGE -dmenu is completely controlled by the keyboard. Items are selected using the -arrow keys, page up, page down, home, and end. -.TP -.B Tab -Copy the selected item to the input field. -.TP -.B Return -Confirm selection. Prints the selected item to stdout and exits, returning -success. -.TP -.B Ctrl-Return -Confirm selection. Prints the selected item to stdout and continues. -.TP -.B Shift\-Return -Confirm input. Prints the input text to stdout and exits, returning success. -.TP -.B Escape -Exit without selecting an item, returning failure. -.TP -.B Ctrl-Left -Move cursor to the start of the current word -.TP -.B Ctrl-Right -Move cursor to the end of the current word -.TP -.B C\-a -Home -.TP -.B C\-b -Left -.TP -.B C\-c -Escape -.TP -.B C\-d -Delete -.TP -.B C\-e -End -.TP -.B C\-f -Right -.TP -.B C\-g -Escape -.TP -.B C\-h -Backspace -.TP -.B C\-i -Tab -.TP -.B C\-j -Return -.TP -.B C\-J -Shift-Return -.TP -.B C\-k -Delete line right -.TP -.B C\-m -Return -.TP -.B C\-M -Shift-Return -.TP -.B C\-n -Down -.TP -.B C\-p -Up -.TP -.B C\-u -Delete line left -.TP -.B C\-w -Delete word left -.TP -.B C\-y -Paste from primary X selection -.TP -.B C\-Y -Paste from X clipboard -.TP -.B M\-b -Move cursor to the start of the current word -.TP -.B M\-f -Move cursor to the end of the current word -.TP -.B M\-g -Home -.TP -.B M\-G -End -.TP -.B M\-h -Up -.TP -.B M\-j -Page down -.TP -.B M\-k -Page up -.TP -.B M\-l -Down -.SH SEE ALSO -.IR dwm (1), -.IR stest (1) diff --git a/dmenu-4.9/dmenu.c b/dmenu-4.9/dmenu.c deleted file mode 100644 index b607411..0000000 --- a/dmenu-4.9/dmenu.c +++ /dev/null @@ -1,855 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#ifdef XINERAMA -#include -#endif -#include - -#include "drw.h" -#include "util.h" - -/* macros */ -#define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \ - * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) -#define LENGTH(X) (sizeof X / sizeof X[0]) -#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) - -/* enums */ -enum { SchemeNorm, SchemeSel, SchemeNormHighlight, SchemeSelHighlight, - SchemeOut, SchemeLast }; /* color schemes */ - - -struct item { - char *text; - struct item *left, *right; - int out; -}; - -static char text[BUFSIZ] = ""; -static char *embed; -static int bh, mw, mh; -static int inputw = 0, promptw; -static int lrpad; /* sum of left and right padding */ -static size_t cursor; -static struct item *items = NULL; -static struct item *matches, *matchend; -static struct item *prev, *curr, *next, *sel; -static int mon = -1, screen; - -static Atom clip, utf8; -static Display *dpy; -static Window root, parentwin, win; -static XIC xic; - -static Drw *drw; -static Clr *scheme[SchemeLast]; - -#include "config.h" - -static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; -static char *(*fstrstr)(const char *, const char *) = strstr; - -static void -appenditem(struct item *item, struct item **list, struct item **last) -{ - if (*last) - (*last)->right = item; - else - *list = item; - - item->left = *last; - item->right = NULL; - *last = item; -} - -static void -calcoffsets(void) -{ - int i, n; - - if (lines > 0) - n = lines * columns * bh; - else - n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">")); - /* calculate which items will begin the next page and previous page */ - for (i = 0, next = curr; next; next = next->right) - if ((i += (lines > 0) ? bh : MIN(TEXTW(next->text), n)) > n) - break; - for (i = 0, prev = curr; prev && prev->left; prev = prev->left) - if ((i += (lines > 0) ? bh : MIN(TEXTW(prev->left->text), n)) > n) - break; -} - -static int -max_textw(void) -{ - int len = 0; - for (struct item *item = items; item && item->text; item++) - len = MAX(TEXTW(item->text), len); - return len; -} - -static void -cleanup(void) -{ - size_t i; - - XUngrabKey(dpy, AnyKey, AnyModifier, root); - for (i = 0; i < SchemeLast; i++) - free(scheme[i]); - drw_free(drw); - XSync(dpy, False); - XCloseDisplay(dpy); -} - -static char * -cistrstr(const char *s, const char *sub) -{ - size_t len; - - for (len = strlen(sub); *s; s++) - if (!strncasecmp(s, sub, len)) - return (char *)s; - return NULL; -} - -static void -drawhighlights(struct item *item, int x, int y, int maxw) -{ - int i, indent; - char *highlight; - char c; - - if (!(strlen(item->text) && strlen(text))) - return; - - drw_setscheme(drw, scheme[item == sel - ? SchemeSelHighlight - : SchemeNormHighlight]); - for (i = 0, highlight = item->text; *highlight && text[i];) { - if (*highlight == text[i]) { - /* get indentation */ - c = *highlight; - *highlight = '\0'; - indent = TEXTW(item->text); - *highlight = c; - - /* highlight character */ - c = highlight[1]; - highlight[1] = '\0'; - drw_text( - drw, - x + indent - (lrpad / 2), - y, - MIN(maxw - indent, TEXTW(highlight) - lrpad), - bh, 0, highlight, 0 - ); - highlight[1] = c; - i++; - } - highlight++; - } -} - - -static int -drawitem(struct item *item, int x, int y, int w) -{ - int r; - if (item == sel) - drw_setscheme(drw, scheme[SchemeSel]); - else if (item->out) - drw_setscheme(drw, scheme[SchemeOut]); - else - drw_setscheme(drw, scheme[SchemeNorm]); - - r = drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); - drawhighlights(item, x, y, w); - return r; -} - -static void -drawmenu(void) -{ - unsigned int curpos; - struct item *item; - int x = 0, y = 0, w; - - drw_setscheme(drw, scheme[SchemeNorm]); - drw_rect(drw, 0, 0, mw, mh, 1, 1); - - if (prompt && *prompt) { - drw_setscheme(drw, scheme[SchemeSel]); - x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0); - } - /* draw input field */ - w = (lines > 0 || !matches) ? mw - x : inputw; - drw_setscheme(drw, scheme[SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0); - - curpos = TEXTW(text) - TEXTW(&text[cursor]); - if ((curpos += lrpad / 2 - 1) < w) { - drw_setscheme(drw, scheme[SchemeNorm]); - drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); - } - - if (lines > 0) { - /* draw grid */ - int i = 0; - for (item = curr; item != next; item = item->right, i++) - drawitem( - item, - x + ((i / lines) * ((mw - x) / columns)), - y + (((i % lines) + 1) * bh), - (mw - x) / columns - ); - } else if (matches) { - /* draw horizontal list */ - x += inputw; - w = TEXTW("<"); - if (curr->left) { - drw_setscheme(drw, scheme[SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, "<", 0); - } - x += w; - for (item = curr; item != next; item = item->right) - x = drawitem(item, x, 0, MIN(TEXTW(item->text), mw - x - TEXTW(">"))); - if (next) { - w = TEXTW(">"); - drw_setscheme(drw, scheme[SchemeNorm]); - drw_text(drw, mw - w, 0, w, bh, lrpad / 2, ">", 0); - } - } - drw_map(drw, win, 0, 0, mw, mh); -} - -static void -grabfocus(void) -{ - struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 }; - Window focuswin; - int i, revertwin; - - for (i = 0; i < 100; ++i) { - XGetInputFocus(dpy, &focuswin, &revertwin); - if (focuswin == win) - return; - XSetInputFocus(dpy, win, RevertToParent, CurrentTime); - nanosleep(&ts, NULL); - } - die("cannot grab focus"); -} - -static void -grabkeyboard(void) -{ - struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 }; - int i; - - if (embed) - return; - /* try to grab keyboard, we may have to wait for another process to ungrab */ - for (i = 0; i < 1000; i++) { - if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, - GrabModeAsync, CurrentTime) == GrabSuccess) - return; - nanosleep(&ts, NULL); - } - die("cannot grab keyboard"); -} - -static void -match(void) -{ - static char **tokv = NULL; - static int tokn = 0; - - char buf[sizeof text], *s; - int i, tokc = 0; - size_t len, textsize; - struct item *item, *lprefix, *lsubstr, *prefixend, *substrend; - - strcpy(buf, text); - /* separate input text into tokens to be matched individually */ - for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " ")) - if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv))) - die("cannot realloc %u bytes:", tokn * sizeof *tokv); - len = tokc ? strlen(tokv[0]) : 0; - - matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; - textsize = strlen(text) + 1; - for (item = items; item && item->text; item++) { - for (i = 0; i < tokc; i++) - if (!fstrstr(item->text, tokv[i])) - break; - if (i != tokc) /* not all tokens match */ - continue; - /* exact matches go first, then prefixes, then substrings */ - if (!tokc || !fstrncmp(text, item->text, textsize)) - appenditem(item, &matches, &matchend); - else if (!fstrncmp(tokv[0], item->text, len)) - appenditem(item, &lprefix, &prefixend); - else - appenditem(item, &lsubstr, &substrend); - } - if (lprefix) { - if (matches) { - matchend->right = lprefix; - lprefix->left = matchend; - } else - matches = lprefix; - matchend = prefixend; - } - if (lsubstr) { - if (matches) { - matchend->right = lsubstr; - lsubstr->left = matchend; - } else - matches = lsubstr; - matchend = substrend; - } - curr = sel = matches; - calcoffsets(); -} - -static void -insert(const char *str, ssize_t n) -{ - if (strlen(text) + n > sizeof text - 1) - return; - /* move existing text out of the way, insert new text, and update cursor */ - memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0)); - if (n > 0) - memcpy(&text[cursor], str, n); - cursor += n; - match(); -} - -static size_t -nextrune(int inc) -{ - ssize_t n; - - /* return location of next utf8 rune in the given direction (+1 or -1) */ - for (n = cursor + inc; n + inc >= 0 && (text[n] & 0xc0) == 0x80; n += inc) - ; - return n; -} - -static void -movewordedge(int dir) -{ - if (dir < 0) { /* move cursor to the start of the word*/ - while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) - cursor = nextrune(-1); - while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) - cursor = nextrune(-1); - } else { /* move cursor to the end of the word */ - while (text[cursor] && strchr(worddelimiters, text[cursor])) - cursor = nextrune(+1); - while (text[cursor] && !strchr(worddelimiters, text[cursor])) - cursor = nextrune(+1); - } -} - -static void -keypress(XKeyEvent *ev) -{ - char buf[32]; - int len; - KeySym ksym; - Status status; - - len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status); - switch (status) { - default: /* XLookupNone, XBufferOverflow */ - return; - case XLookupChars: - goto insert; - case XLookupKeySym: - case XLookupBoth: - break; - } - - if (ev->state & ControlMask) { - switch(ksym) { - case XK_a: ksym = XK_Home; break; - case XK_b: ksym = XK_Left; break; - case XK_c: ksym = XK_Escape; break; - case XK_d: ksym = XK_Delete; break; - case XK_e: ksym = XK_End; break; - case XK_f: ksym = XK_Right; break; - case XK_g: ksym = XK_Escape; break; - case XK_h: ksym = XK_BackSpace; break; - case XK_i: ksym = XK_Tab; break; - case XK_j: /* fallthrough */ - case XK_J: /* fallthrough */ - case XK_m: /* fallthrough */ - case XK_M: ksym = XK_Return; ev->state &= ~ControlMask; break; - case XK_n: ksym = XK_Down; break; - case XK_p: ksym = XK_Up; break; - - case XK_k: /* delete right */ - text[cursor] = '\0'; - match(); - break; - case XK_u: /* delete left */ - insert(NULL, 0 - cursor); - break; - case XK_w: /* delete word */ - while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) - insert(NULL, nextrune(-1) - cursor); - while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) - insert(NULL, nextrune(-1) - cursor); - break; - case XK_y: /* paste selection */ - case XK_Y: - XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, - utf8, utf8, win, CurrentTime); - return; - case XK_Left: - movewordedge(-1); - goto draw; - case XK_Right: - movewordedge(+1); - goto draw; - case XK_Return: - case XK_KP_Enter: - break; - case XK_bracketleft: - cleanup(); - exit(1); - default: - return; - } - } else if (ev->state & Mod1Mask) { - switch(ksym) { - case XK_b: - movewordedge(-1); - goto draw; - case XK_f: - movewordedge(+1); - goto draw; - case XK_g: ksym = XK_Home; break; - case XK_G: ksym = XK_End; break; - case XK_h: ksym = XK_Up; break; - case XK_j: ksym = XK_Next; break; - case XK_k: ksym = XK_Prior; break; - case XK_l: ksym = XK_Down; break; - default: - return; - } - } - - switch(ksym) { - default: -insert: - if (!iscntrl(*buf)) - insert(buf, len); - break; - case XK_Delete: - if (text[cursor] == '\0') - return; - cursor = nextrune(+1); - /* fallthrough */ - case XK_BackSpace: - if (cursor == 0) - return; - insert(NULL, nextrune(-1) - cursor); - break; - case XK_End: - if (text[cursor] != '\0') { - cursor = strlen(text); - break; - } - if (next) { - /* jump to end of list and position items in reverse */ - curr = matchend; - calcoffsets(); - curr = prev; - calcoffsets(); - while (next && (curr = curr->right)) - calcoffsets(); - } - sel = matchend; - break; - case XK_Escape: - cleanup(); - exit(1); - case XK_Home: - if (sel == matches) { - cursor = 0; - break; - } - sel = curr = matches; - calcoffsets(); - break; - case XK_Left: - if (cursor > 0 && (!sel || !sel->left || lines > 0)) { - cursor = nextrune(-1); - break; - } - if (lines > 0) - return; - /* fallthrough */ - case XK_Up: - if (sel && sel->left && (sel = sel->left)->right == curr) { - curr = prev; - calcoffsets(); - } - break; - case XK_Next: - if (!next) - return; - sel = curr = next; - calcoffsets(); - break; - case XK_Prior: - if (!prev) - return; - sel = curr = prev; - calcoffsets(); - break; - case XK_Return: - case XK_KP_Enter: - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); - if (!(ev->state & ControlMask)) { - cleanup(); - exit(0); - } - if (sel) - sel->out = 1; - break; - case XK_Right: - if (text[cursor] != '\0') { - cursor = nextrune(+1); - break; - } - if (lines > 0) - return; - /* fallthrough */ - case XK_Down: - if (sel && sel->right && (sel = sel->right) == next) { - curr = next; - calcoffsets(); - } - break; - case XK_Tab: - if (!sel) - return; - strncpy(text, sel->text, sizeof text - 1); - text[sizeof text - 1] = '\0'; - cursor = strlen(text); - match(); - break; - } - -draw: - drawmenu(); -} - -static void -paste(void) -{ - char *p, *q; - int di; - unsigned long dl; - Atom da; - - /* we have been given the current selection, now insert it into input */ - if (XGetWindowProperty(dpy, win, utf8, 0, (sizeof text / 4) + 1, False, - utf8, &da, &di, &dl, &dl, (unsigned char **)&p) - == Success && p) { - insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p)); - XFree(p); - } - drawmenu(); -} - -static void -readstdin(void) -{ - char buf[sizeof text], *p; - size_t i, imax = 0, size = 0; - unsigned int tmpmax = 0; - - /* read each line from stdin and add it to the item list */ - for (i = 0; fgets(buf, sizeof buf, stdin); i++) { - if (i + 1 >= size / sizeof *items) - if (!(items = realloc(items, (size += BUFSIZ)))) - die("cannot realloc %u bytes:", size); - if ((p = strchr(buf, '\n'))) - *p = '\0'; - if (!(items[i].text = strdup(buf))) - die("cannot strdup %u bytes:", strlen(buf) + 1); - items[i].out = 0; - drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL); - if (tmpmax > inputw) { - inputw = tmpmax; - imax = i; - } - } - if (items) - items[i].text = NULL; - inputw = items ? TEXTW(items[imax].text) : 0; - lines = MIN(lines, i); -} - -static void -run(void) -{ - XEvent ev; - - while (!XNextEvent(dpy, &ev)) { - if (XFilterEvent(&ev, None)) - continue; - switch(ev.type) { - case Expose: - if (ev.xexpose.count == 0) - drw_map(drw, win, 0, 0, mw, mh); - break; - case FocusIn: - /* regrab focus from parent window */ - if (ev.xfocus.window != win) - grabfocus(); - break; - case KeyPress: - keypress(&ev.xkey); - break; - case SelectionNotify: - if (ev.xselection.property == utf8) - paste(); - break; - case VisibilityNotify: - if (ev.xvisibility.state != VisibilityUnobscured) - XRaiseWindow(dpy, win); - break; - } - } -} - -static void -setup(void) -{ - int x, y, i, j; - unsigned int du; - XSetWindowAttributes swa; - XIM xim; - Window w, dw, *dws; - XWindowAttributes wa; - XClassHint ch = {"dmenu", "dmenu"}; -#ifdef XINERAMA - XineramaScreenInfo *info; - Window pw; - int a, di, n, area = 0; -#endif - /* init appearance */ - for (j = 0; j < SchemeLast; j++) - scheme[j] = drw_scm_create(drw, colors[j], 2); - - clip = XInternAtom(dpy, "CLIPBOARD", False); - utf8 = XInternAtom(dpy, "UTF8_STRING", False); - - /* calculate menu geometry */ - bh = drw->fonts->h + 2; - lines = MAX(lines, 0); - mh = (lines + 1) * bh; - promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; -#ifdef XINERAMA - i = 0; - if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { - XGetInputFocus(dpy, &w, &di); - if (mon >= 0 && mon < n) - i = mon; - else if (w != root && w != PointerRoot && w != None) { - /* find top-level window containing current input focus */ - do { - if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws) - XFree(dws); - } while (w != root && w != pw); - /* find xinerama screen with which the window intersects most */ - if (XGetWindowAttributes(dpy, pw, &wa)) - for (j = 0; j < n; j++) - if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) { - area = a; - i = j; - } - } - /* no focused window is on screen, so use pointer location instead */ - if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) - for (i = 0; i < n; i++) - if (INTERSECT(x, y, 1, 1, info[i])) - break; - - if (centered) { - mw = MIN(MAX(max_textw() + promptw, min_width), info[i].width); - x = info[i].x_org + ((info[i].width - mw) / 2); - y = info[i].y_org + ((info[i].height - mh) / 2); - } else { - x = info[i].x_org; - y = info[i].y_org + (topbar ? 0 : info[i].height - mh); - mw = info[i].width; - } - - XFree(info); - } else -#endif - { - if (!XGetWindowAttributes(dpy, parentwin, &wa)) - die("could not get embedding window attributes: 0x%lx", - parentwin); - - if (centered) { - mw = MIN(MAX(max_textw() + promptw, min_width), wa.width); - x = (wa.width - mw) / 2; - y = (wa.height - mh) / 2; - } else { - x = 0; - y = topbar ? 0 : wa.height - mh; - mw = wa.width; - } - } - inputw = MIN(inputw, mw/3); - match(); - - /* create menu window */ - swa.override_redirect = True; - swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; - swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width, - CopyFromParent, CopyFromParent, CopyFromParent, - CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); - XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel); - XSetClassHint(dpy, win, &ch); - - /* open input methods */ - xim = XOpenIM(dpy, NULL, NULL, NULL); - xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, - XNClientWindow, win, XNFocusWindow, win, NULL); - - XMapRaised(dpy, win); - XSetInputFocus(dpy, win, RevertToParent, CurrentTime); - if (embed) { - XSelectInput(dpy, parentwin, FocusChangeMask); - if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) { - for (i = 0; i < du && dws[i] != win; ++i) - XSelectInput(dpy, dws[i], FocusChangeMask); - XFree(dws); - } - grabfocus(); - } - drw_resize(drw, mw, mh); - drawmenu(); -} - -static void -usage(void) -{ - fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" - " [-nb color] [-nf color] [-sb color] [-sf color]\n" - " [-nhb color] [-nhf color] [-shb color] [-shf color] [-w windowid]\n", stderr); - exit(1); -} - -int -main(int argc, char *argv[]) -{ - XWindowAttributes wa; - int i, fast = 0; - - for (i = 1; i < argc; i++) - /* these options take no arguments */ - if (!strcmp(argv[i], "-v")) { /* prints version information */ - puts("dmenu-"VERSION); - exit(0); - } else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ - topbar = 0; - else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ - fast = 1; - else if (!strcmp(argv[i], "-c")) /* centers dmenu on screen */ - centered = 1; - else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ - fstrncmp = strncasecmp; - fstrstr = cistrstr; - } else if (i + 1 == argc) - usage(); - /* these options take one argument */ - else if (!strcmp(argv[i], "-g")) { /* number of columns in grid */ - columns = atoi(argv[++i]); - if (lines == 0) lines = 1; - } else if (!strcmp(argv[i], "-l")) { /* number of lines in grid */ - lines = atoi(argv[++i]); - if (columns == 0) columns = 1; - } else if (!strcmp(argv[i], "-m")) - mon = atoi(argv[++i]); - else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ - prompt = argv[++i]; - else if (!strcmp(argv[i], "-fn")) /* font or font set */ - fonts[0] = argv[++i]; - else if (!strcmp(argv[i], "-nb")) /* normal background color */ - colors[SchemeNorm][ColBg] = argv[++i]; - else if (!strcmp(argv[i], "-nf")) /* normal foreground color */ - colors[SchemeNorm][ColFg] = argv[++i]; - else if (!strcmp(argv[i], "-sb")) /* selected background color */ - colors[SchemeSel][ColBg] = argv[++i]; - else if (!strcmp(argv[i], "-sf")) /* selected foreground color */ - colors[SchemeSel][ColFg] = argv[++i]; - else if (!strcmp(argv[i], "-nhb")) /* normal hi background color */ - colors[SchemeNormHighlight][ColBg] = argv[++i]; - else if (!strcmp(argv[i], "-nhf")) /* normal hi foreground color */ - colors[SchemeNormHighlight][ColFg] = argv[++i]; - else if (!strcmp(argv[i], "-shb")) /* selected hi background color */ - colors[SchemeSelHighlight][ColBg] = argv[++i]; - else if (!strcmp(argv[i], "-shf")) /* selected hi foreground color */ - colors[SchemeSelHighlight][ColFg] = argv[++i]; - else if (!strcmp(argv[i], "-w")) /* embedding window id */ - embed = argv[++i]; - else - usage(); - - if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fputs("warning: no locale support\n", stderr); - if (!XSetLocaleModifiers("")) - fputs("warning: no locale modifiers support\n", stderr); - if (!(dpy = XOpenDisplay(NULL))) - die("cannot open display"); - screen = DefaultScreen(dpy); - root = RootWindow(dpy, screen); - if (!embed || !(parentwin = strtol(embed, NULL, 0))) - parentwin = root; - if (!XGetWindowAttributes(dpy, parentwin, &wa)) - die("could not get embedding window attributes: 0x%lx", - parentwin); - drw = drw_create(dpy, screen, root, wa.width, wa.height); - if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) - die("no fonts could be loaded."); - lrpad = drw->fonts->h; - -#ifdef __OpenBSD__ - if (pledge("stdio rpath", NULL) == -1) - die("pledge"); -#endif - - if (fast && !isatty(0)) { - grabkeyboard(); - readstdin(); - } else { - readstdin(); - grabkeyboard(); - } - setup(); - run(); - - return 1; /* unreachable */ -} diff --git a/dmenu-4.9/dmenu.c.orig b/dmenu-4.9/dmenu.c.orig deleted file mode 100644 index d245075..0000000 --- a/dmenu-4.9/dmenu.c.orig +++ /dev/null @@ -1,802 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#ifdef XINERAMA -#include -#endif -#include - -#include "drw.h" -#include "util.h" - -/* macros */ -#define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \ - * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) -#define LENGTH(X) (sizeof X / sizeof X[0]) -#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) - -/* enums */ -enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ - -struct item { - char *text; - struct item *left, *right; - int out; -}; - -static char text[BUFSIZ] = ""; -static char *embed; -static int bh, mw, mh; -static int inputw = 0, promptw; -static int lrpad; /* sum of left and right padding */ -static size_t cursor; -static struct item *items = NULL; -static struct item *matches, *matchend; -static struct item *prev, *curr, *next, *sel; -static int mon = -1, screen; - -static Atom clip, utf8; -static Display *dpy; -static Window root, parentwin, win; -static XIC xic; - -static Drw *drw; -static Clr *scheme[SchemeLast]; - -#include "config.h" - -static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; -static char *(*fstrstr)(const char *, const char *) = strstr; - -static void -appenditem(struct item *item, struct item **list, struct item **last) -{ - if (*last) - (*last)->right = item; - else - *list = item; - - item->left = *last; - item->right = NULL; - *last = item; -} - -static void -calcoffsets(void) -{ - int i, n; - - if (lines > 0) - n = lines * columns * bh; - else - n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">")); - /* calculate which items will begin the next page and previous page */ - for (i = 0, next = curr; next; next = next->right) - if ((i += (lines > 0) ? bh : MIN(TEXTW(next->text), n)) > n) - break; - for (i = 0, prev = curr; prev && prev->left; prev = prev->left) - if ((i += (lines > 0) ? bh : MIN(TEXTW(prev->left->text), n)) > n) - break; -} - -static int -max_textw(void) -{ - int len = 0; - for (struct item *item = items; item && item->text; item++) - len = MAX(TEXTW(item->text), len); - return len; -} - -static void -cleanup(void) -{ - size_t i; - - XUngrabKey(dpy, AnyKey, AnyModifier, root); - for (i = 0; i < SchemeLast; i++) - free(scheme[i]); - drw_free(drw); - XSync(dpy, False); - XCloseDisplay(dpy); -} - -static char * -cistrstr(const char *s, const char *sub) -{ - size_t len; - - for (len = strlen(sub); *s; s++) - if (!strncasecmp(s, sub, len)) - return (char *)s; - return NULL; -} - -static int -drawitem(struct item *item, int x, int y, int w) -{ - if (item == sel) - drw_setscheme(drw, scheme[SchemeSel]); - else if (item->out) - drw_setscheme(drw, scheme[SchemeOut]); - else - drw_setscheme(drw, scheme[SchemeNorm]); - - return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); -} - -static void -drawmenu(void) -{ - unsigned int curpos; - struct item *item; - int x = 0, y = 0, w; - - drw_setscheme(drw, scheme[SchemeNorm]); - drw_rect(drw, 0, 0, mw, mh, 1, 1); - - if (prompt && *prompt) { - drw_setscheme(drw, scheme[SchemeSel]); - x = drw_text(drw, x, 0, promptw, bh, lrpad / 2, prompt, 0); - } - /* draw input field */ - w = (lines > 0 || !matches) ? mw - x : inputw; - drw_setscheme(drw, scheme[SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0); - - curpos = TEXTW(text) - TEXTW(&text[cursor]); - if ((curpos += lrpad / 2 - 1) < w) { - drw_setscheme(drw, scheme[SchemeNorm]); - drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); - } - - if (lines > 0) { - /* draw grid */ - int i = 0; - for (item = curr; item != next; item = item->right, i++) - drawitem( - item, - x + ((i / lines) * ((mw - x) / columns)), - y + (((i % lines) + 1) * bh), - (mw - x) / columns - ); - } else if (matches) { - /* draw horizontal list */ - x += inputw; - w = TEXTW("<"); - if (curr->left) { - drw_setscheme(drw, scheme[SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, "<", 0); - } - x += w; - for (item = curr; item != next; item = item->right) - x = drawitem(item, x, 0, MIN(TEXTW(item->text), mw - x - TEXTW(">"))); - if (next) { - w = TEXTW(">"); - drw_setscheme(drw, scheme[SchemeNorm]); - drw_text(drw, mw - w, 0, w, bh, lrpad / 2, ">", 0); - } - } - drw_map(drw, win, 0, 0, mw, mh); -} - -static void -grabfocus(void) -{ - struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 }; - Window focuswin; - int i, revertwin; - - for (i = 0; i < 100; ++i) { - XGetInputFocus(dpy, &focuswin, &revertwin); - if (focuswin == win) - return; - XSetInputFocus(dpy, win, RevertToParent, CurrentTime); - nanosleep(&ts, NULL); - } - die("cannot grab focus"); -} - -static void -grabkeyboard(void) -{ - struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 }; - int i; - - if (embed) - return; - /* try to grab keyboard, we may have to wait for another process to ungrab */ - for (i = 0; i < 1000; i++) { - if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, - GrabModeAsync, CurrentTime) == GrabSuccess) - return; - nanosleep(&ts, NULL); - } - die("cannot grab keyboard"); -} - -static void -match(void) -{ - static char **tokv = NULL; - static int tokn = 0; - - char buf[sizeof text], *s; - int i, tokc = 0; - size_t len, textsize; - struct item *item, *lprefix, *lsubstr, *prefixend, *substrend; - - strcpy(buf, text); - /* separate input text into tokens to be matched individually */ - for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " ")) - if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv))) - die("cannot realloc %u bytes:", tokn * sizeof *tokv); - len = tokc ? strlen(tokv[0]) : 0; - - matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL; - textsize = strlen(text) + 1; - for (item = items; item && item->text; item++) { - for (i = 0; i < tokc; i++) - if (!fstrstr(item->text, tokv[i])) - break; - if (i != tokc) /* not all tokens match */ - continue; - /* exact matches go first, then prefixes, then substrings */ - if (!tokc || !fstrncmp(text, item->text, textsize)) - appenditem(item, &matches, &matchend); - else if (!fstrncmp(tokv[0], item->text, len)) - appenditem(item, &lprefix, &prefixend); - else - appenditem(item, &lsubstr, &substrend); - } - if (lprefix) { - if (matches) { - matchend->right = lprefix; - lprefix->left = matchend; - } else - matches = lprefix; - matchend = prefixend; - } - if (lsubstr) { - if (matches) { - matchend->right = lsubstr; - lsubstr->left = matchend; - } else - matches = lsubstr; - matchend = substrend; - } - curr = sel = matches; - calcoffsets(); -} - -static void -insert(const char *str, ssize_t n) -{ - if (strlen(text) + n > sizeof text - 1) - return; - /* move existing text out of the way, insert new text, and update cursor */ - memmove(&text[cursor + n], &text[cursor], sizeof text - cursor - MAX(n, 0)); - if (n > 0) - memcpy(&text[cursor], str, n); - cursor += n; - match(); -} - -static size_t -nextrune(int inc) -{ - ssize_t n; - - /* return location of next utf8 rune in the given direction (+1 or -1) */ - for (n = cursor + inc; n + inc >= 0 && (text[n] & 0xc0) == 0x80; n += inc) - ; - return n; -} - -static void -movewordedge(int dir) -{ - if (dir < 0) { /* move cursor to the start of the word*/ - while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) - cursor = nextrune(-1); - while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) - cursor = nextrune(-1); - } else { /* move cursor to the end of the word */ - while (text[cursor] && strchr(worddelimiters, text[cursor])) - cursor = nextrune(+1); - while (text[cursor] && !strchr(worddelimiters, text[cursor])) - cursor = nextrune(+1); - } -} - -static void -keypress(XKeyEvent *ev) -{ - char buf[32]; - int len; - KeySym ksym; - Status status; - - len = XmbLookupString(xic, ev, buf, sizeof buf, &ksym, &status); - switch (status) { - default: /* XLookupNone, XBufferOverflow */ - return; - case XLookupChars: - goto insert; - case XLookupKeySym: - case XLookupBoth: - break; - } - - if (ev->state & ControlMask) { - switch(ksym) { - case XK_a: ksym = XK_Home; break; - case XK_b: ksym = XK_Left; break; - case XK_c: ksym = XK_Escape; break; - case XK_d: ksym = XK_Delete; break; - case XK_e: ksym = XK_End; break; - case XK_f: ksym = XK_Right; break; - case XK_g: ksym = XK_Escape; break; - case XK_h: ksym = XK_BackSpace; break; - case XK_i: ksym = XK_Tab; break; - case XK_j: /* fallthrough */ - case XK_J: /* fallthrough */ - case XK_m: /* fallthrough */ - case XK_M: ksym = XK_Return; ev->state &= ~ControlMask; break; - case XK_n: ksym = XK_Down; break; - case XK_p: ksym = XK_Up; break; - - case XK_k: /* delete right */ - text[cursor] = '\0'; - match(); - break; - case XK_u: /* delete left */ - insert(NULL, 0 - cursor); - break; - case XK_w: /* delete word */ - while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)])) - insert(NULL, nextrune(-1) - cursor); - while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)])) - insert(NULL, nextrune(-1) - cursor); - break; - case XK_y: /* paste selection */ - case XK_Y: - XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, - utf8, utf8, win, CurrentTime); - return; - case XK_Left: - movewordedge(-1); - goto draw; - case XK_Right: - movewordedge(+1); - goto draw; - case XK_Return: - case XK_KP_Enter: - break; - case XK_bracketleft: - cleanup(); - exit(1); - default: - return; - } - } else if (ev->state & Mod1Mask) { - switch(ksym) { - case XK_b: - movewordedge(-1); - goto draw; - case XK_f: - movewordedge(+1); - goto draw; - case XK_g: ksym = XK_Home; break; - case XK_G: ksym = XK_End; break; - case XK_h: ksym = XK_Up; break; - case XK_j: ksym = XK_Next; break; - case XK_k: ksym = XK_Prior; break; - case XK_l: ksym = XK_Down; break; - default: - return; - } - } - - switch(ksym) { - default: -insert: - if (!iscntrl(*buf)) - insert(buf, len); - break; - case XK_Delete: - if (text[cursor] == '\0') - return; - cursor = nextrune(+1); - /* fallthrough */ - case XK_BackSpace: - if (cursor == 0) - return; - insert(NULL, nextrune(-1) - cursor); - break; - case XK_End: - if (text[cursor] != '\0') { - cursor = strlen(text); - break; - } - if (next) { - /* jump to end of list and position items in reverse */ - curr = matchend; - calcoffsets(); - curr = prev; - calcoffsets(); - while (next && (curr = curr->right)) - calcoffsets(); - } - sel = matchend; - break; - case XK_Escape: - cleanup(); - exit(1); - case XK_Home: - if (sel == matches) { - cursor = 0; - break; - } - sel = curr = matches; - calcoffsets(); - break; - case XK_Left: - if (cursor > 0 && (!sel || !sel->left || lines > 0)) { - cursor = nextrune(-1); - break; - } - if (lines > 0) - return; - /* fallthrough */ - case XK_Up: - if (sel && sel->left && (sel = sel->left)->right == curr) { - curr = prev; - calcoffsets(); - } - break; - case XK_Next: - if (!next) - return; - sel = curr = next; - calcoffsets(); - break; - case XK_Prior: - if (!prev) - return; - sel = curr = prev; - calcoffsets(); - break; - case XK_Return: - case XK_KP_Enter: - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); - if (!(ev->state & ControlMask)) { - cleanup(); - exit(0); - } - if (sel) - sel->out = 1; - break; - case XK_Right: - if (text[cursor] != '\0') { - cursor = nextrune(+1); - break; - } - if (lines > 0) - return; - /* fallthrough */ - case XK_Down: - if (sel && sel->right && (sel = sel->right) == next) { - curr = next; - calcoffsets(); - } - break; - case XK_Tab: - if (!sel) - return; - strncpy(text, sel->text, sizeof text - 1); - text[sizeof text - 1] = '\0'; - cursor = strlen(text); - match(); - break; - } - -draw: - drawmenu(); -} - -static void -paste(void) -{ - char *p, *q; - int di; - unsigned long dl; - Atom da; - - /* we have been given the current selection, now insert it into input */ - if (XGetWindowProperty(dpy, win, utf8, 0, (sizeof text / 4) + 1, False, - utf8, &da, &di, &dl, &dl, (unsigned char **)&p) - == Success && p) { - insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p)); - XFree(p); - } - drawmenu(); -} - -static void -readstdin(void) -{ - char buf[sizeof text], *p; - size_t i, imax = 0, size = 0; - unsigned int tmpmax = 0; - - /* read each line from stdin and add it to the item list */ - for (i = 0; fgets(buf, sizeof buf, stdin); i++) { - if (i + 1 >= size / sizeof *items) - if (!(items = realloc(items, (size += BUFSIZ)))) - die("cannot realloc %u bytes:", size); - if ((p = strchr(buf, '\n'))) - *p = '\0'; - if (!(items[i].text = strdup(buf))) - die("cannot strdup %u bytes:", strlen(buf) + 1); - items[i].out = 0; - drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL); - if (tmpmax > inputw) { - inputw = tmpmax; - imax = i; - } - } - if (items) - items[i].text = NULL; - inputw = items ? TEXTW(items[imax].text) : 0; - lines = MIN(lines, i); -} - -static void -run(void) -{ - XEvent ev; - - while (!XNextEvent(dpy, &ev)) { - if (XFilterEvent(&ev, None)) - continue; - switch(ev.type) { - case Expose: - if (ev.xexpose.count == 0) - drw_map(drw, win, 0, 0, mw, mh); - break; - case FocusIn: - /* regrab focus from parent window */ - if (ev.xfocus.window != win) - grabfocus(); - break; - case KeyPress: - keypress(&ev.xkey); - break; - case SelectionNotify: - if (ev.xselection.property == utf8) - paste(); - break; - case VisibilityNotify: - if (ev.xvisibility.state != VisibilityUnobscured) - XRaiseWindow(dpy, win); - break; - } - } -} - -static void -setup(void) -{ - int x, y, i, j; - unsigned int du; - XSetWindowAttributes swa; - XIM xim; - Window w, dw, *dws; - XWindowAttributes wa; - XClassHint ch = {"dmenu", "dmenu"}; -#ifdef XINERAMA - XineramaScreenInfo *info; - Window pw; - int a, di, n, area = 0; -#endif - /* init appearance */ - for (j = 0; j < SchemeLast; j++) - scheme[j] = drw_scm_create(drw, colors[j], 2); - - clip = XInternAtom(dpy, "CLIPBOARD", False); - utf8 = XInternAtom(dpy, "UTF8_STRING", False); - - /* calculate menu geometry */ - bh = drw->fonts->h + 2; - lines = MAX(lines, 0); - mh = (lines + 1) * bh; - promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; -#ifdef XINERAMA - i = 0; - if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { - XGetInputFocus(dpy, &w, &di); - if (mon >= 0 && mon < n) - i = mon; - else if (w != root && w != PointerRoot && w != None) { - /* find top-level window containing current input focus */ - do { - if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws) - XFree(dws); - } while (w != root && w != pw); - /* find xinerama screen with which the window intersects most */ - if (XGetWindowAttributes(dpy, pw, &wa)) - for (j = 0; j < n; j++) - if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) { - area = a; - i = j; - } - } - /* no focused window is on screen, so use pointer location instead */ - if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) - for (i = 0; i < n; i++) - if (INTERSECT(x, y, 1, 1, info[i])) - break; - - if (centered) { - mw = MIN(MAX(max_textw() + promptw, min_width), info[i].width); - x = info[i].x_org + ((info[i].width - mw) / 2); - y = info[i].y_org + ((info[i].height - mh) / 2); - } else { - x = info[i].x_org; - y = info[i].y_org + (topbar ? 0 : info[i].height - mh); - mw = info[i].width; - } - - XFree(info); - } else -#endif - { - if (!XGetWindowAttributes(dpy, parentwin, &wa)) - die("could not get embedding window attributes: 0x%lx", - parentwin); - - if (centered) { - mw = MIN(MAX(max_textw() + promptw, min_width), wa.width); - x = (wa.width - mw) / 2; - y = (wa.height - mh) / 2; - } else { - x = 0; - y = topbar ? 0 : wa.height - mh; - mw = wa.width; - } - } - inputw = MIN(inputw, mw/3); - match(); - - /* create menu window */ - swa.override_redirect = True; - swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; - swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width, - CopyFromParent, CopyFromParent, CopyFromParent, - CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); - XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel); - XSetClassHint(dpy, win, &ch); - - /* open input methods */ - xim = XOpenIM(dpy, NULL, NULL, NULL); - xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, - XNClientWindow, win, XNFocusWindow, win, NULL); - - XMapRaised(dpy, win); - XSetInputFocus(dpy, win, RevertToParent, CurrentTime); - if (embed) { - XSelectInput(dpy, parentwin, FocusChangeMask); - if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) { - for (i = 0; i < du && dws[i] != win; ++i) - XSelectInput(dpy, dws[i], FocusChangeMask); - XFree(dws); - } - grabfocus(); - } - drw_resize(drw, mw, mh); - drawmenu(); -} - -static void -usage(void) -{ - fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" - " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr); - exit(1); -} - -int -main(int argc, char *argv[]) -{ - XWindowAttributes wa; - int i, fast = 0; - - for (i = 1; i < argc; i++) - /* these options take no arguments */ - if (!strcmp(argv[i], "-v")) { /* prints version information */ - puts("dmenu-"VERSION); - exit(0); - } else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ - topbar = 0; - else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ - fast = 1; - else if (!strcmp(argv[i], "-c")) /* centers dmenu on screen */ - centered = 1; - else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ - fstrncmp = strncasecmp; - fstrstr = cistrstr; - } else if (i + 1 == argc) - usage(); - /* these options take one argument */ - else if (!strcmp(argv[i], "-g")) { /* number of columns in grid */ - columns = atoi(argv[++i]); - if (lines == 0) lines = 1; - } else if (!strcmp(argv[i], "-l")) { /* number of lines in grid */ - lines = atoi(argv[++i]); - if (columns == 0) columns = 1; - } else if (!strcmp(argv[i], "-m")) - mon = atoi(argv[++i]); - else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ - prompt = argv[++i]; - else if (!strcmp(argv[i], "-fn")) /* font or font set */ - fonts[0] = argv[++i]; - else if (!strcmp(argv[i], "-nb")) /* normal background color */ - colors[SchemeNorm][ColBg] = argv[++i]; - else if (!strcmp(argv[i], "-nf")) /* normal foreground color */ - colors[SchemeNorm][ColFg] = argv[++i]; - else if (!strcmp(argv[i], "-sb")) /* selected background color */ - colors[SchemeSel][ColBg] = argv[++i]; - else if (!strcmp(argv[i], "-sf")) /* selected foreground color */ - colors[SchemeSel][ColFg] = argv[++i]; - else if (!strcmp(argv[i], "-w")) /* embedding window id */ - embed = argv[++i]; - else - usage(); - - if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fputs("warning: no locale support\n", stderr); - if (!XSetLocaleModifiers("")) - fputs("warning: no locale modifiers support\n", stderr); - if (!(dpy = XOpenDisplay(NULL))) - die("cannot open display"); - screen = DefaultScreen(dpy); - root = RootWindow(dpy, screen); - if (!embed || !(parentwin = strtol(embed, NULL, 0))) - parentwin = root; - if (!XGetWindowAttributes(dpy, parentwin, &wa)) - die("could not get embedding window attributes: 0x%lx", - parentwin); - drw = drw_create(dpy, screen, root, wa.width, wa.height); - if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) - die("no fonts could be loaded."); - lrpad = drw->fonts->h; - -#ifdef __OpenBSD__ - if (pledge("stdio rpath", NULL) == -1) - die("pledge"); -#endif - - if (fast && !isatty(0)) { - grabkeyboard(); - readstdin(); - } else { - readstdin(); - grabkeyboard(); - } - setup(); - run(); - - return 1; /* unreachable */ -} diff --git a/dmenu-4.9/dmenu.c.rej b/dmenu-4.9/dmenu.c.rej deleted file mode 100644 index dd978c8..0000000 --- a/dmenu-4.9/dmenu.c.rej +++ /dev/null @@ -1,14 +0,0 @@ ---- dmenu.c 2019-02-02 13:55:02.000000000 +0100 -+++ dmenu.c 2019-05-19 02:11:20.966710117 +0200 -@@ -654,9 +654,10 @@ setup(void) - swa.override_redirect = True; - swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; - swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; -- win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0, -+ win = XCreateWindow(dpy, parentwin, x, y, mw, mh, border_width, - CopyFromParent, CopyFromParent, CopyFromParent, - CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); -+ XSetWindowBorder(dpy, win, scheme[SchemeSel][ColBg].pixel); - XSetClassHint(dpy, win, &ch); - - /* open input methods */ diff --git a/dmenu-4.9/dmenu_path b/dmenu-4.9/dmenu_path deleted file mode 100644 index 3a7cda7..0000000 --- a/dmenu-4.9/dmenu_path +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -cachedir="${XDG_CACHE_HOME:-"$HOME/.cache"}" -cache="$cachedir/dmenu_run" - -[ ! -e "$cachedir" ] && mkdir -p "$cachedir" - -IFS=: -if stest -dqr -n "$cache" $PATH; then - stest -flx $PATH | sort -u | tee "$cache" -else - cat "$cache" -fi diff --git a/dmenu-4.9/dmenu_run b/dmenu-4.9/dmenu_run deleted file mode 100755 index 834ede5..0000000 --- a/dmenu-4.9/dmenu_run +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} & diff --git a/dmenu-4.9/drw.c b/dmenu-4.9/drw.c deleted file mode 100644 index 9fc940e..0000000 --- a/dmenu-4.9/drw.c +++ /dev/null @@ -1,430 +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); - free(drw); -} - -/* This function is an implementation detail. Library users should use - * drw_fontset_create instead. - */ -static Fnt * -xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern) -{ - Fnt *font; - XftFont *xfont = NULL; - FcPattern *pattern = NULL; - - if (fontname) { - /* Using the pattern found at font->xfont->pattern does not yield the - * same substitution results as using the pattern returned by - * FcNameParse; using the latter results in the desired fallback - * behaviour whereas the former just results in missing-character - * rectangles being drawn, at least with some fonts. */ - if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) { - fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname); - return NULL; - } - if (!(pattern = FcNameParse((FcChar8 *) fontname))) { - fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname); - XftFontClose(drw->dpy, xfont); - return NULL; - } - } else if (fontpattern) { - if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) { - fprintf(stderr, "error, cannot load font from pattern.\n"); - return NULL; - } - } else { - die("no font specified."); - } - - /* Do not allow using color fonts. This is a workaround for a BadLength - * error from Xft with color glyphs. Modelled on the Xterm workaround. See - * https://bugzilla.redhat.com/show_bug.cgi?id=1498269 - * https://lists.suckless.org/dev/1701/30932.html - * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349 - * and lots more all over the internet. - */ - - 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) -{ - char buf[1024]; - int ty; - unsigned int ew; - XftDraw *d = NULL; - Fnt *usedfont, *curfont, *nextfont; - size_t i, len; - int utf8strlen, utf8charlen, render = x || y || w || h; - long utf8codepoint = 0; - const char *utf8str; - FcCharSet *fccharset; - FcPattern *fcpattern; - FcPattern *match; - XftResult result; - int charexists = 0; - - if (!drw || (render && !drw->scheme) || !text || !drw->fonts) - return 0; - - if (!render) { - w = ~w; - } else { - XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); - XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); - d = XftDrawCreate(drw->dpy, drw->drawable, - DefaultVisual(drw->dpy, drw->screen), - DefaultColormap(drw->dpy, drw->screen)); - x += lpad; - w -= lpad; - } - - usedfont = drw->fonts; - while (1) { - utf8strlen = 0; - utf8str = text; - nextfont = NULL; - while (*text) { - utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ); - for (curfont = drw->fonts; curfont; curfont = curfont->next) { - charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); - if (charexists) { - if (curfont == usedfont) { - utf8strlen += utf8charlen; - text += utf8charlen; - } else { - nextfont = curfont; - } - break; - } - } - - if (!charexists || nextfont) - break; - else - charexists = 0; - } - - if (utf8strlen) { - drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL); - /* shorten text if necessary */ - for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--) - drw_font_getexts(usedfont, utf8str, len, &ew, NULL); - - if (len) { - memcpy(buf, utf8str, len); - buf[len] = '\0'; - if (len < utf8strlen) - for (i = len; i && i > len - 3; buf[--i] = '.') - ; /* NOP */ - - if (render) { - ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; - XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], - usedfont->xfont, x, ty, (XftChar8 *)buf, len); - } - x += ew; - w -= ew; - } - } - - if (!*text) { - break; - } else if (nextfont) { - charexists = 0; - usedfont = nextfont; - } else { - /* Regardless of whether or not a fallback font is found, the - * character must be drawn. */ - charexists = 1; - - fccharset = FcCharSetCreate(); - FcCharSetAddChar(fccharset, utf8codepoint); - - if (!drw->fonts->pattern) { - /* Refer to the comment in xfont_create for more information. */ - die("the first font in the cache must be loaded from a font string."); - } - - fcpattern = FcPatternDuplicate(drw->fonts->pattern); - FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); - FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); - FcPatternAddBool(fcpattern, FC_COLOR, FcFalse); - - FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); - FcDefaultSubstitute(fcpattern); - match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result); - - FcCharSetDestroy(fccharset); - FcPatternDestroy(fcpattern); - - if (match) { - usedfont = xfont_create(drw, NULL, match); - if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) { - for (curfont = drw->fonts; curfont->next; curfont = curfont->next) - ; /* NOP */ - curfont->next = usedfont; - } else { - xfont_free(usedfont); - usedfont = drw->fonts; - } - } - } - } - if (d) - XftDrawDestroy(d); - - return x + (render ? w : 0); -} - -void -drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) -{ - if (!drw) - return; - - XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); - XSync(drw->dpy, False); -} - -unsigned int -drw_fontset_getwidth(Drw *drw, const char *text) -{ - if (!drw || !drw->fonts || !text) - return 0; - return drw_text(drw, 0, 0, 0, 0, 0, text, 0); -} - -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/dmenu-4.9/drw.h b/dmenu-4.9/drw.h deleted file mode 100644 index 4c67419..0000000 --- a/dmenu-4.9/drw.h +++ /dev/null @@ -1,57 +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 }; /* 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); -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/dmenu-4.9/fuzzyhighlight.diff b/dmenu-4.9/fuzzyhighlight.diff deleted file mode 100644 index 58d5c6f..0000000 --- a/dmenu-4.9/fuzzyhighlight.diff +++ /dev/null @@ -1,152 +0,0 @@ -Author: Chris Noxz -note: This patch is meant to be used together with fuzzymatch - -diff -upN dmenu-4.9/config.def.h dmenu-4.9-fuzzyhighlight/config.def.h ---- dmenu-4.9/config.def.h 2019-02-02 13:55:02.000000000 +0100 -+++ dmenu-4.9-fuzzyhighlight/config.def.h 2020-04-04 10:26:36.990890854 +0200 -@@ -11,6 +11,8 @@ static const char *colors[SchemeLast][2] - /* fg bg */ - [SchemeNorm] = { "#bbbbbb", "#222222" }, - [SchemeSel] = { "#eeeeee", "#005577" }, -+ [SchemeSelHighlight] = { "#ffc978", "#005577" }, -+ [SchemeNormHighlight] = { "#ffc978", "#222222" }, - [SchemeOut] = { "#000000", "#00ffff" }, - }; - /* -l option; if nonzero, dmenu uses vertical list with given number of lines */ -diff -upN dmenu-4.9/dmenu.1 dmenu-4.9-fuzzyhighlight/dmenu.1 ---- dmenu-4.9/dmenu.1 2019-02-02 13:55:02.000000000 +0100 -+++ dmenu-4.9-fuzzyhighlight/dmenu.1 2020-04-04 10:30:16.430054933 +0200 -@@ -20,6 +20,14 @@ dmenu \- dynamic menu - .IR color ] - .RB [ \-sf - .IR color ] -+.RB [ \-nhb -+.IR color ] -+.RB [ \-nhf -+.IR color ] -+.RB [ \-shb -+.IR color ] -+.RB [ \-shf -+.IR color ] - .RB [ \-w - .IR windowid ] - .P -@@ -75,6 +83,18 @@ defines the selected background color. - .BI \-sf " color" - defines the selected foreground color. - .TP -+.BI \-nhb " color" -+defines the normal highlight background color. -+.TP -+.BI \-nhf " color" -+defines the normal highlight foreground color. -+.TP -+.BI \-shb " color" -+defines the selected highlight background color. -+.TP -+.BI \-shf " color" -+defines the selected highlight foreground color. -+.TP - .B \-v - prints version information to stdout, then exits. - .TP -diff -upN dmenu-4.9/dmenu.c dmenu-4.9-fuzzyhighlight/dmenu.c ---- dmenu-4.9/dmenu.c 2019-02-02 13:55:02.000000000 +0100 -+++ dmenu-4.9-fuzzyhighlight/dmenu.c 2020-04-04 10:27:43.888026309 +0200 -@@ -26,7 +26,9 @@ - #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) - - /* enums */ --enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ -+enum { SchemeNorm, SchemeSel, SchemeNormHighlight, SchemeSelHighlight, -+ SchemeOut, SchemeLast }; /* color schemes */ -+ - - struct item { - char *text; -@@ -113,9 +115,49 @@ cistrstr(const char *s, const char *sub) - return NULL; - } - -+static void -+drawhighlights(struct item *item, int x, int y, int maxw) -+{ -+ int i, indent; -+ char *highlight; -+ char c; -+ -+ if (!(strlen(item->text) && strlen(text))) -+ return; -+ -+ drw_setscheme(drw, scheme[item == sel -+ ? SchemeSelHighlight -+ : SchemeNormHighlight]); -+ for (i = 0, highlight = item->text; *highlight && text[i];) { -+ if (*highlight == text[i]) { -+ /* get indentation */ -+ c = *highlight; -+ *highlight = '\0'; -+ indent = TEXTW(item->text); -+ *highlight = c; -+ -+ /* highlight character */ -+ c = highlight[1]; -+ highlight[1] = '\0'; -+ drw_text( -+ drw, -+ x + indent - (lrpad / 2), -+ y, -+ MIN(maxw - indent, TEXTW(highlight) - lrpad), -+ bh, 0, highlight, 0 -+ ); -+ highlight[1] = c; -+ i++; -+ } -+ highlight++; -+ } -+} -+ -+ - static int - drawitem(struct item *item, int x, int y, int w) - { -+ int r; - if (item == sel) - drw_setscheme(drw, scheme[SchemeSel]); - else if (item->out) -@@ -123,7 +165,9 @@ drawitem(struct item *item, int x, int y - else - drw_setscheme(drw, scheme[SchemeNorm]); - -- return drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); -+ r = drw_text(drw, x, y, w, bh, lrpad / 2, item->text, 0); -+ drawhighlights(item, x, y, w); -+ return r; - } - - static void -@@ -683,7 +727,8 @@ static void - usage(void) - { - fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" -- " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr); -+ " [-nb color] [-nf color] [-sb color] [-sf color]\n" -+ " [-nhb color] [-nhf color] [-shb color] [-shf color] [-w windowid]\n", stderr); - exit(1); - } - -@@ -724,6 +769,14 @@ main(int argc, char *argv[]) - colors[SchemeSel][ColBg] = argv[++i]; - else if (!strcmp(argv[i], "-sf")) /* selected foreground color */ - colors[SchemeSel][ColFg] = argv[++i]; -+ else if (!strcmp(argv[i], "-nhb")) /* normal hi background color */ -+ colors[SchemeNormHighlight][ColBg] = argv[++i]; -+ else if (!strcmp(argv[i], "-nhf")) /* normal hi foreground color */ -+ colors[SchemeNormHighlight][ColFg] = argv[++i]; -+ else if (!strcmp(argv[i], "-shb")) /* selected hi background color */ -+ colors[SchemeSelHighlight][ColBg] = argv[++i]; -+ else if (!strcmp(argv[i], "-shf")) /* selected hi foreground color */ -+ colors[SchemeSelHighlight][ColFg] = argv[++i]; - else if (!strcmp(argv[i], "-w")) /* embedding window id */ - embed = argv[++i]; - else diff --git a/dmenu-4.9/grid.diff b/dmenu-4.9/grid.diff deleted file mode 100644 index c27689b..0000000 --- a/dmenu-4.9/grid.diff +++ /dev/null @@ -1,107 +0,0 @@ -From 39ab9676914bd0d8105d0f96bbd7611a53077438 Mon Sep 17 00:00:00 2001 -From: Miles Alan -Date: Sat, 4 Jul 2020 11:19:04 -0500 -Subject: [PATCH] Add -g option to display entries in the given number of grid - columns - -This option can be used in conjunction with -l to format dmenu's options in -arbitrary size grids. For example, to create a 4 column by 6 line grid, you -could use: dmenu -g 4 -l 6 ---- - config.def.h | 3 ++- - dmenu.1 | 7 ++++++- - dmenu.c | 22 ++++++++++++++++------ - 3 files changed, 24 insertions(+), 8 deletions(-) - -diff --git a/config.def.h b/config.def.h -index 1edb647..96cf3c9 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -13,8 +13,9 @@ static const char *colors[SchemeLast][2] = { - [SchemeSel] = { "#eeeeee", "#005577" }, - [SchemeOut] = { "#000000", "#00ffff" }, - }; --/* -l option; if nonzero, dmenu uses vertical list with given number of lines */ -+/* -l and -g options; controls number of lines and columns in grid if > 0 */ - static unsigned int lines = 0; -+static unsigned int columns = 0; - - /* - * Characters not considered part of a word while deleting words -diff --git a/dmenu.1 b/dmenu.1 -index 323f93c..d0a734a 100644 ---- a/dmenu.1 -+++ b/dmenu.1 -@@ -4,6 +4,8 @@ dmenu \- dynamic menu - .SH SYNOPSIS - .B dmenu - .RB [ \-bfiv ] -+.RB [ \-g -+.IR columns ] - .RB [ \-l - .IR lines ] - .RB [ \-m -@@ -47,8 +49,11 @@ is faster, but will lock up X until stdin reaches end\-of\-file. - .B \-i - dmenu matches menu items case insensitively. - .TP -+.BI \-g " columns" -+dmenu lists items in a grid with the given number of columns. -+.TP - .BI \-l " lines" --dmenu lists items vertically, with the given number of lines. -+dmenu lists items in a grid with the given number of lines. - .TP - .BI \-m " monitor" - dmenu is displayed on the monitor number supplied. Monitor numbers are starting -diff --git a/dmenu.c b/dmenu.c -index 6b8f51b..d79b6bb 100644 ---- a/dmenu.c -+++ b/dmenu.c -@@ -77,7 +77,7 @@ calcoffsets(void) - int i, n; - - if (lines > 0) -- n = lines * bh; -+ n = lines * columns * bh; - else - n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">")); - /* calculate which items will begin the next page and previous page */ -@@ -152,9 +152,15 @@ drawmenu(void) - } - - if (lines > 0) { -- /* draw vertical list */ -- for (item = curr; item != next; item = item->right) -- drawitem(item, x, y += bh, mw - x); -+ /* draw grid */ -+ int i = 0; -+ for (item = curr; item != next; item = item->right, i++) -+ drawitem( -+ item, -+ x + ((i / lines) * ((mw - x) / columns)), -+ y + (((i % lines) + 1) * bh), -+ (mw - x) / columns -+ ); - } else if (matches) { - /* draw horizontal list */ - x += inputw; -@@ -708,9 +714,13 @@ main(int argc, char *argv[]) - } else if (i + 1 == argc) - usage(); - /* these options take one argument */ -- else if (!strcmp(argv[i], "-l")) /* number of lines in vertical list */ -+ else if (!strcmp(argv[i], "-g")) { /* number of columns in grid */ -+ columns = atoi(argv[++i]); -+ if (lines == 0) lines = 1; -+ } else if (!strcmp(argv[i], "-l")) { /* number of lines in grid */ - lines = atoi(argv[++i]); -- else if (!strcmp(argv[i], "-m")) -+ if (columns == 0) columns = 1; -+ } else if (!strcmp(argv[i], "-m")) - mon = atoi(argv[++i]); - else if (!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ - prompt = argv[++i]; --- -2.23.1 - diff --git a/dmenu-4.9/stest b/dmenu-4.9/stest deleted file mode 100755 index c93eed0aabd6b4ee4f747c9cb34b7bb157cf0469..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17744 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 diff --git a/dmenu-4.9/stest.1 b/dmenu-4.9/stest.1 deleted file mode 100644 index 2667d8a..0000000 --- a/dmenu-4.9/stest.1 +++ /dev/null @@ -1,90 +0,0 @@ -.TH STEST 1 dmenu\-VERSION -.SH NAME -stest \- filter a list of files by properties -.SH SYNOPSIS -.B stest -.RB [ -abcdefghlpqrsuwx ] -.RB [ -n -.IR file ] -.RB [ -o -.IR file ] -.RI [ file ...] -.SH DESCRIPTION -.B stest -takes a list of files and filters by the files' properties, analogous to -.IR test (1). -Files which pass all tests are printed to stdout. If no files are given, stest -reads files from stdin. -.SH OPTIONS -.TP -.B \-a -Test hidden files. -.TP -.B \-b -Test that files are block specials. -.TP -.B \-c -Test that files are character specials. -.TP -.B \-d -Test that files are directories. -.TP -.B \-e -Test that files exist. -.TP -.B \-f -Test that files are regular files. -.TP -.B \-g -Test that files have their set-group-ID flag set. -.TP -.B \-h -Test that files are symbolic links. -.TP -.B \-l -Test the contents of a directory given as an argument. -.TP -.BI \-n " file" -Test that files are newer than -.IR file . -.TP -.BI \-o " file" -Test that files are older than -.IR file . -.TP -.B \-p -Test that files are named pipes. -.TP -.B \-q -No files are printed, only the exit status is returned. -.TP -.B \-r -Test that files are readable. -.TP -.B \-s -Test that files are not empty. -.TP -.B \-u -Test that files have their set-user-ID flag set. -.TP -.B \-v -Invert the sense of tests, only failing files pass. -.TP -.B \-w -Test that files are writable. -.TP -.B \-x -Test that files are executable. -.SH EXIT STATUS -.TP -.B 0 -At least one file passed all tests. -.TP -.B 1 -No files passed all tests. -.TP -.B 2 -An error occurred. -.SH SEE ALSO -.IR dmenu (1), -.IR test (1) diff --git a/dmenu-4.9/stest.c b/dmenu-4.9/stest.c deleted file mode 100644 index 7a7b0bc..0000000 --- a/dmenu-4.9/stest.c +++ /dev/null @@ -1,109 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include - -#include -#include -#include -#include -#include -#include - -#include "arg.h" -char *argv0; - -#define FLAG(x) (flag[(x)-'a']) - -static void test(const char *, const char *); -static void usage(void); - -static int match = 0; -static int flag[26]; -static struct stat old, new; - -static void -test(const char *path, const char *name) -{ - struct stat st, ln; - - if ((!stat(path, &st) && (FLAG('a') || name[0] != '.') /* hidden files */ - && (!FLAG('b') || S_ISBLK(st.st_mode)) /* block special */ - && (!FLAG('c') || S_ISCHR(st.st_mode)) /* character special */ - && (!FLAG('d') || S_ISDIR(st.st_mode)) /* directory */ - && (!FLAG('e') || access(path, F_OK) == 0) /* exists */ - && (!FLAG('f') || S_ISREG(st.st_mode)) /* regular file */ - && (!FLAG('g') || st.st_mode & S_ISGID) /* set-group-id flag */ - && (!FLAG('h') || (!lstat(path, &ln) && S_ISLNK(ln.st_mode))) /* symbolic link */ - && (!FLAG('n') || st.st_mtime > new.st_mtime) /* newer than file */ - && (!FLAG('o') || st.st_mtime < old.st_mtime) /* older than file */ - && (!FLAG('p') || S_ISFIFO(st.st_mode)) /* named pipe */ - && (!FLAG('r') || access(path, R_OK) == 0) /* readable */ - && (!FLAG('s') || st.st_size > 0) /* not empty */ - && (!FLAG('u') || st.st_mode & S_ISUID) /* set-user-id flag */ - && (!FLAG('w') || access(path, W_OK) == 0) /* writable */ - && (!FLAG('x') || access(path, X_OK) == 0)) != FLAG('v')) { /* executable */ - if (FLAG('q')) - exit(0); - match = 1; - puts(name); - } -} - -static void -usage(void) -{ - fprintf(stderr, "usage: %s [-abcdefghlpqrsuvwx] " - "[-n file] [-o file] [file...]\n", argv0); - exit(2); /* like test(1) return > 1 on error */ -} - -int -main(int argc, char *argv[]) -{ - struct dirent *d; - char path[PATH_MAX], *line = NULL, *file; - size_t linesiz = 0; - ssize_t n; - DIR *dir; - int r; - - ARGBEGIN { - case 'n': /* newer than file */ - case 'o': /* older than file */ - file = EARGF(usage()); - if (!(FLAG(ARGC()) = !stat(file, (ARGC() == 'n' ? &new : &old)))) - perror(file); - break; - default: - /* miscellaneous operators */ - if (strchr("abcdefghlpqrsuvwx", ARGC())) - FLAG(ARGC()) = 1; - else - usage(); /* unknown flag */ - } ARGEND; - - if (!argc) { - /* read list from stdin */ - while ((n = getline(&line, &linesiz, stdin)) > 0) { - if (n && line[n - 1] == '\n') - line[n - 1] = '\0'; - test(line, line); - } - free(line); - } else { - for (; argc; argc--, argv++) { - if (FLAG('l') && (dir = opendir(*argv))) { - /* test directory contents */ - while ((d = readdir(dir))) { - r = snprintf(path, sizeof path, "%s/%s", - *argv, d->d_name); - if (r >= 0 && (size_t)r < sizeof path) - test(path, d->d_name); - } - closedir(dir); - } else { - test(*argv, *argv); - } - } - } - return match ? 0 : 1; -} diff --git a/dmenu-4.9/util.c b/dmenu-4.9/util.c deleted file mode 100644 index fe044fc..0000000 --- a/dmenu-4.9/util.c +++ /dev/null @@ -1,35 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include -#include -#include -#include - -#include "util.h" - -void * -ecalloc(size_t nmemb, size_t size) -{ - void *p; - - if (!(p = calloc(nmemb, size))) - die("calloc:"); - return p; -} - -void -die(const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - - if (fmt[0] && fmt[strlen(fmt)-1] == ':') { - fputc(' ', stderr); - perror(NULL); - } else { - fputc('\n', stderr); - } - - exit(1); -} diff --git a/dmenu-4.9/util.h b/dmenu-4.9/util.h deleted file mode 100644 index f633b51..0000000 --- a/dmenu-4.9/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/dwm-6.2/LICENSE b/dwm-6.2/LICENSE deleted file mode 100644 index d221f09..0000000 --- a/dwm-6.2/LICENSE +++ /dev/null @@ -1,37 +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 - -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/dwm-6.2/Makefile b/dwm-6.2/Makefile deleted file mode 100644 index 77bcbc0..0000000 --- a/dwm-6.2/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/dwm-6.2/README b/dwm-6.2/README deleted file mode 100644 index 95d4fd0..0000000 --- a/dwm-6.2/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/dwm-6.2/config.def.h b/dwm-6.2/config.def.h deleted file mode 100644 index 63479fa..0000000 --- a/dwm-6.2/config.def.h +++ /dev/null @@ -1,201 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* appearance */ -static const unsigned int borderpx = 3; /* border pixel of windows */ -static const unsigned int gappx = 10; /* gap pixel between windows */ -static const unsigned int snap = 32; /* snap pixel */ -static const unsigned int gappih = 10; /* horiz inner gap between windows */ -static const unsigned int gappiv = 10; /* vert inner gap between windows */ -static const unsigned int gappoh = 20; /* horiz outer gap between windows and screen edge */ -static const unsigned int gappov = 20; /* vert outer gap between windows and screen edge */ -static const int smartgaps = 0; /* 1 means no outer gap when there is only one window */ -static const int showbar = 1; /* 0 means no bar */ -static const int topbar = 1; /* 0 means bottom bar */ -static const char *fonts[] = { "Mononoki Nerd Font:size=10", "JoyPixels:pixelsize=12:antialias=true:autohint=true" }; -static const char dmenufont[] = "Mononoki Nerd Font:size=16"; -static const char col_gray1[] = "#282828"; -static const char col_gray2[] = "#928374"; -static const char col_gray3[] = "#d5c4a1"; -static const char col_gray4[] = "#ebdbb2"; -static const char col_cyan[] = "#3c3836"; -static const char col_norm[] = "#d65d0e"; -static const char col_norm2[] = "#b16286"; -static const char col_norm3[] = "#d79921"; -static const char *colors[][3] = { - /* fg bg border */ - [SchemeNorm] = { col_norm, col_cyan, col_cyan}, - - [SchemeSel] = { col_gray4, col_norm2, col_norm3 }, - [SchemeStatus] = { col_norm2, col_cyan, "#000000" }, // Statusbar right {text,background,not used but cannot be empty} - - [SchemeTagsSel] = { col_gray1, col_norm3, "#000000" }, // Tagbar left selected {text,background,not used but cannot be empty} - [SchemeTagsNorm] = { col_norm2, col_cyan, "#000000" }, // Tagbar left unselected {text,background,not used but cannot be empty} - - [SchemeInfoSel] = { col_gray4, col_cyan, "#000000" }, // infobar middle selected {text,background,not used but cannot be empty} - [SchemeInfoNorm] = { col_norm2, col_cyan, "#000000" }, // infobar middle unselected {text,background,not used but cannot be empty} -}; - -static const char *const autostart[] = { - //"$HOME/.dwm/autostart.sh", NULL, - /*"pulsemixer", "-k", NULL, - "firefox", NULL, - "variety", NULL, - "redshift", NULL, - "picom", "--experimental-backends", "--detect-rounded-corners", NULL, - "setxkbmap","us,ru,fi",",winkeys","grp:alt_shift_toggle", NULL, - "$HOME/.local/scripts/status/launch", NULL, - "enact", "--pos", "top", NULL, - "pulseaudio","-k", NULL, - */ - NULL /* terminate */ -}; - -/* tagging */ -static const char *tags[] = { "ﳎ ", " ", " ", " ", "", "", " ", " ", "龎 " }; -static const char *tagsalt[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - -/* launcher commands (They must be NULL terminated) */ -static const char* spotify[] = { "spotify", "spotify", NULL }; - -static const Launcher launchers[] = { - /* command name to display */ - { spotify, "阮 " }, -}; - - -static const Rule rules[] = { - /* xprop(1): - * WM_CLASS(STRING) = instance, class - * WM_NAME(STRING) = title - */ -/* class instance title tags mask isfloating monitor scratch key */ -{ "Gimp", NULL, NULL, 0, 1, -1, 0 }, -{ "firefox", NULL, NULL, 1 << 1, 0, -1, 0 }, -{ "Spotify Premium", NULL, NULL, 7 , 0, -1, 0 }, -{ NULL, NULL, "scratchpad", 0, 1, -1, 's' }, -{ NULL, NULL, "sp_volume", 0, 1, -1, 'v' }, -{ NULL, NULL, "Todoist", 0, 1, -1, 't' }, -{ NULL, NULL, "PomoDoneApp", 0, 1, -1, 'p' }, -{ NULL, NULL, "ScratchEmacs", 0, 1, -1, 'e' }, -{ NULL, NULL, "Task - No Summary", 0, 1, -1, 0 } -}; -// default gaps -/* 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 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, "-c", "-l", "20", NULL}; -static const char *termcmd[] = { "alacritty", NULL }; -static const char *flameshot[] = { "flameshot","gui", NULL }; -static const char *deadd_notify[] = { "/home/horhik/.local/scripts/deadd_notify", NULL}; - -/*First arg only serves to match against key in rules*/ -static const char *scratchpadcmd[] = {"s", "alacritty", "-t", "scratchpad", NULL}; -static const char *sp_emacs[] = {"e", "emacs", "-T", "ScratchEmacs", NULL}; -static const char *sp_volume_control[] = {"v","alacritty", "-t", "sp_volume","-e", "pulsemixer", NULL}; -static const char *tasks[] = {"t","todoist", NULL}; -static const char *pomo[] = {"p","pomodone", NULL}; -static Key keys[] = { - /* modifier key function argument */ - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY|ShiftMask, XK_s, spawn, {.v = flameshot } }, - { MODKEY|Mod1Mask, XK_space, spawn, {.v = deadd_notify } }, - { 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|Mod1Mask, XK_h, incrgaps, {.i = +1 } }, - { MODKEY|Mod1Mask, XK_l, incrgaps, {.i = -10 } }, - { MODKEY|Mod1Mask|ShiftMask, XK_h, incrogaps, {.i = +10 } }, - { MODKEY|Mod1Mask|ShiftMask, XK_l, incrogaps, {.i = -10 } }, - { MODKEY|Mod1Mask|ControlMask, XK_h, incrigaps, {.i = +10 } }, - { MODKEY|Mod1Mask|ControlMask, XK_l, incrigaps, {.i = -10 } }, - { MODKEY|Mod1Mask, XK_0, togglegaps, {0} }, - { MODKEY|Mod1Mask|ShiftMask, XK_0, defaultgaps, {0} }, - { MODKEY, XK_y, incrihgaps, {.i = +10 } }, - { MODKEY, XK_o, incrihgaps, {.i = -10 } }, - { MODKEY|ControlMask, XK_y, incrivgaps, {.i = +10 } }, - { MODKEY|ControlMask, XK_o, incrivgaps, {.i = -10 } }, - { MODKEY|Mod1Mask, XK_y, incrohgaps, {.i = +10 } }, - { MODKEY|Mod1Mask, XK_o, incrohgaps, {.i = -10 } }, - { MODKEY|ShiftMask, XK_y, incrovgaps, {.i = +10 } }, - { MODKEY|ShiftMask, XK_o, incrovgaps, {.i = -10 } }, - { 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|ShiftMask, XK_f, togglefullscr, {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 } }, - { MODKEY, XK_minus, setgaps, {.i = -5 } }, - { MODKEY, XK_equal, setgaps, {.i = +5 } }, - { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, - /*SCRATCHPADS*/ - { MODKEY, XK_u, togglescratch, {.v = scratchpadcmd } }, - { MODKEY|ShiftMask, XK_m, togglescratch, {.v = sp_volume_control } }, - { MODKEY, XK_e, togglescratch, {.v = sp_emacs } }, - { MODKEY|ShiftMask, XK_d, togglescratch, {.v = tasks } }, - { MODKEY|ShiftMask, XK_e, togglescratch, {.v = pomo } }, - { MODKEY, XK_n, togglealttag, {0} }, - TAGKEYS( XK_1, 0) - TAGKEYS( XK_2, 1) - TAGKEYS( XK_3, 2) - TAGKEYS( XK_4, 3) - TAGKEYS( XK_5, 4) - TAGKEYS( XK_6, 5) - TAGKEYS( XK_7, 6) - TAGKEYS( XK_8, 7) - TAGKEYS( XK_9, 8) - { MODKEY|ShiftMask, XK_q, quit, {0} }, -}; - -/* button definitions */ -/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ -static Button buttons[] = { - /* click event mask button function argument */ - { ClkLtSymbol, 0, Button1, setlayout, {0} }, - { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, - { ClkWinTitle, 0, Button2, zoom, {0} }, - { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, - { ClkClientWin, MODKEY, Button1, movemouse, {0} }, - { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, - { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, - { ClkTagBar, 0, Button1, view, {0} }, - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, -}; - diff --git a/dwm-6.2/config.def.h.orig b/dwm-6.2/config.def.h.orig deleted file mode 100644 index eca04d5..0000000 --- a/dwm-6.2/config.def.h.orig +++ /dev/null @@ -1,177 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* appearance */ -static const unsigned int borderpx = 3; /* border pixel of windows */ -static const unsigned int gappx = 10; /* gap pixel between 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[] = { "Mononoki Nerd Font:size=10"}; -static const char dmenufont[] = "Mononoki Nerd Font:size=16"; -static const char col_gray1[] = "#282828"; -static const char col_gray2[] = "#928374"; -static const char col_gray3[] = "#d5c4a1"; -static const char col_gray4[] = "#ebdbb2"; -static const char col_cyan[] = "#3c3836"; -static const char col_norm[] = "#d65d0e"; -static const char col_norm2[] = "#b16286"; -static const char col_norm3[] = "#d79921"; -static const char *colors[][3] = { - /* fg bg border */ - [SchemeNorm] = { col_norm, col_cyan, col_cyan}, - - [SchemeSel] = { col_gray4, col_norm2, col_norm3 }, - [SchemeStatus] = { col_norm2, col_cyan, "#000000" }, // Statusbar right {text,background,not used but cannot be empty} - - [SchemeTagsSel] = { col_gray1, col_norm3, "#000000" }, // Tagbar left selected {text,background,not used but cannot be empty} - [SchemeTagsNorm] = { col_norm2, col_cyan, "#000000" }, // Tagbar left unselected {text,background,not used but cannot be empty} - - [SchemeInfoSel] = { col_gray4, col_cyan, "#000000" }, // infobar middle selected {text,background,not used but cannot be empty} - [SchemeInfoNorm] = { col_norm2, col_cyan, "#000000" }, // infobar middle unselected {text,background,not used but cannot be empty} -}; - -static const char *const autostart[] = { - //"$HOME/.dwm/autostart.sh", NULL, - /*"pulsemixer", "-k", NULL, - "firefox", NULL, - "variety", NULL, - "redshift", NULL, - "picom", "--experimental-backends", "--detect-rounded-corners", NULL, - "setxkbmap","us,ru,fi",",winkeys","grp:alt_shift_toggle", NULL, - "$HOME/.local/scripts/status/launch", NULL, - "enact", "--pos", "top", NULL, - "pulseaudio","-k", NULL, - */ - NULL /* terminate */ -}; - -/* tagging */ -static const char *tags[] = { "ﳎ ", " ", " ", " ", "", "", " ", " ", "龎 " }; -static const char *tagsalt[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - -/* launcher commands (They must be NULL terminated) */ -static const char* spotify[] = { "spotify", "spotify", NULL }; - -static const Launcher launchers[] = { - /* command name to display */ - { spotify, "阮 " }, -}; - - -static const Rule rules[] = { - /* xprop(1): - * WM_CLASS(STRING) = instance, class - * WM_NAME(STRING) = title - */ -/* class instance title tags mask isfloating monitor scratch key */ -{ "Gimp", NULL, NULL, 0, 1, -1, 0 }, -{ "firefox", NULL, NULL, 1 << 1, 0, -1, 0 }, -{ "spotify", NULL, NULL, 7 , 0, -1, 0 }, -{ NULL, NULL, "scratchpad", 0, 1, -1, 's' }, -{ NULL, NULL, "sp_volume", 0, 1, -1, 'v' }, -{ NULL, NULL, "ScratchEmacs", 0, 1, -1, 'e' }, -{ "Evolution", NULL, "Tasks - Evolution", 0, 1, -1, 't' }, -{ NULL, NULL, "Task - No Summary", 0, 1, -1, 0 } -}; - -/* 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 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, "-c", "-l", "20", NULL}; -static const char *termcmd[] = { "alacritty", NULL }; -static const char *flameshot[] = { "flameshot","gui", NULL }; - -/*First arg only serves to match against key in rules*/ -static const char *scratchpadcmd[] = {"s", "alacritty", "-t", "scratchpad", NULL}; -static const char *sp_emacs[] = {"e", "emacs", "-T", "ScratchEmacs", NULL}; -static const char *sp_volume_control[] = {"v","alacritty", "-t", "sp_volume","-e", "pulsemixer", NULL}; -static const char *tasks[] = {"t","evolution", NULL}; - - -static Key keys[] = { - /* modifier key function argument */ - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY|ShiftMask, XK_s, spawn, {.v = flameshot } }, - { 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|ShiftMask, XK_f, togglefullscr, {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 } }, - { MODKEY, XK_minus, setgaps, {.i = -5 } }, - { MODKEY, XK_equal, setgaps, {.i = +5 } }, - { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, - /*SCRATCHPADS*/ - { MODKEY, XK_u, togglescratch, {.v = scratchpadcmd } }, - { MODKEY|ShiftMask, XK_m, togglescratch, {.v = sp_volume_control } }, - { MODKEY, XK_e, togglescratch, {.v = sp_emacs } }, - { MODKEY, XK_t, togglescratch, {.v = tasks } }, - { MODKEY, XK_n, togglealttag, {0} }, - TAGKEYS( XK_1, 0) - TAGKEYS( XK_2, 1) - TAGKEYS( XK_3, 2) - TAGKEYS( XK_4, 3) - TAGKEYS( XK_5, 4) - TAGKEYS( XK_6, 5) - TAGKEYS( XK_7, 6) - TAGKEYS( XK_8, 7) - TAGKEYS( XK_9, 8) - { MODKEY|ShiftMask, XK_q, quit, {0} }, -}; - -/* button definitions */ -/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ -static Button buttons[] = { - /* click event mask button function argument */ - { ClkLtSymbol, 0, Button1, setlayout, {0} }, - { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, - { ClkWinTitle, 0, Button2, zoom, {0} }, - { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, - { ClkClientWin, MODKEY, Button1, movemouse, {0} }, - { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, - { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, - { ClkTagBar, 0, Button1, view, {0} }, - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, -}; - diff --git a/dwm-6.2/config.def.h.rej b/dwm-6.2/config.def.h.rej deleted file mode 100644 index 8f3d02b..0000000 --- a/dwm-6.2/config.def.h.rej +++ /dev/null @@ -1,18 +0,0 @@ ---- config.def.h -+++ config.def.h -@@ -20,6 +20,7 @@ static const char *colors[][3] = { - - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; -+static const char *tagsalt[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - - static const Rule rules[] = { - /* xprop(1): -@@ -84,6 +85,7 @@ static Key keys[] = { - { MODKEY, XK_period, focusmon, {.i = +1 } }, - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, - { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, -+ { MODKEY, XK_n, togglealttag, {0} }, - TAGKEYS( XK_1, 0) - TAGKEYS( XK_2, 1) - TAGKEYS( XK_3, 2) diff --git a/dwm-6.2/config.h b/dwm-6.2/config.h deleted file mode 100644 index 63479fa..0000000 --- a/dwm-6.2/config.h +++ /dev/null @@ -1,201 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* appearance */ -static const unsigned int borderpx = 3; /* border pixel of windows */ -static const unsigned int gappx = 10; /* gap pixel between windows */ -static const unsigned int snap = 32; /* snap pixel */ -static const unsigned int gappih = 10; /* horiz inner gap between windows */ -static const unsigned int gappiv = 10; /* vert inner gap between windows */ -static const unsigned int gappoh = 20; /* horiz outer gap between windows and screen edge */ -static const unsigned int gappov = 20; /* vert outer gap between windows and screen edge */ -static const int smartgaps = 0; /* 1 means no outer gap when there is only one window */ -static const int showbar = 1; /* 0 means no bar */ -static const int topbar = 1; /* 0 means bottom bar */ -static const char *fonts[] = { "Mononoki Nerd Font:size=10", "JoyPixels:pixelsize=12:antialias=true:autohint=true" }; -static const char dmenufont[] = "Mononoki Nerd Font:size=16"; -static const char col_gray1[] = "#282828"; -static const char col_gray2[] = "#928374"; -static const char col_gray3[] = "#d5c4a1"; -static const char col_gray4[] = "#ebdbb2"; -static const char col_cyan[] = "#3c3836"; -static const char col_norm[] = "#d65d0e"; -static const char col_norm2[] = "#b16286"; -static const char col_norm3[] = "#d79921"; -static const char *colors[][3] = { - /* fg bg border */ - [SchemeNorm] = { col_norm, col_cyan, col_cyan}, - - [SchemeSel] = { col_gray4, col_norm2, col_norm3 }, - [SchemeStatus] = { col_norm2, col_cyan, "#000000" }, // Statusbar right {text,background,not used but cannot be empty} - - [SchemeTagsSel] = { col_gray1, col_norm3, "#000000" }, // Tagbar left selected {text,background,not used but cannot be empty} - [SchemeTagsNorm] = { col_norm2, col_cyan, "#000000" }, // Tagbar left unselected {text,background,not used but cannot be empty} - - [SchemeInfoSel] = { col_gray4, col_cyan, "#000000" }, // infobar middle selected {text,background,not used but cannot be empty} - [SchemeInfoNorm] = { col_norm2, col_cyan, "#000000" }, // infobar middle unselected {text,background,not used but cannot be empty} -}; - -static const char *const autostart[] = { - //"$HOME/.dwm/autostart.sh", NULL, - /*"pulsemixer", "-k", NULL, - "firefox", NULL, - "variety", NULL, - "redshift", NULL, - "picom", "--experimental-backends", "--detect-rounded-corners", NULL, - "setxkbmap","us,ru,fi",",winkeys","grp:alt_shift_toggle", NULL, - "$HOME/.local/scripts/status/launch", NULL, - "enact", "--pos", "top", NULL, - "pulseaudio","-k", NULL, - */ - NULL /* terminate */ -}; - -/* tagging */ -static const char *tags[] = { "ﳎ ", " ", " ", " ", "", "", " ", " ", "龎 " }; -static const char *tagsalt[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - -/* launcher commands (They must be NULL terminated) */ -static const char* spotify[] = { "spotify", "spotify", NULL }; - -static const Launcher launchers[] = { - /* command name to display */ - { spotify, "阮 " }, -}; - - -static const Rule rules[] = { - /* xprop(1): - * WM_CLASS(STRING) = instance, class - * WM_NAME(STRING) = title - */ -/* class instance title tags mask isfloating monitor scratch key */ -{ "Gimp", NULL, NULL, 0, 1, -1, 0 }, -{ "firefox", NULL, NULL, 1 << 1, 0, -1, 0 }, -{ "Spotify Premium", NULL, NULL, 7 , 0, -1, 0 }, -{ NULL, NULL, "scratchpad", 0, 1, -1, 's' }, -{ NULL, NULL, "sp_volume", 0, 1, -1, 'v' }, -{ NULL, NULL, "Todoist", 0, 1, -1, 't' }, -{ NULL, NULL, "PomoDoneApp", 0, 1, -1, 'p' }, -{ NULL, NULL, "ScratchEmacs", 0, 1, -1, 'e' }, -{ NULL, NULL, "Task - No Summary", 0, 1, -1, 0 } -}; -// default gaps -/* 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 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, "-c", "-l", "20", NULL}; -static const char *termcmd[] = { "alacritty", NULL }; -static const char *flameshot[] = { "flameshot","gui", NULL }; -static const char *deadd_notify[] = { "/home/horhik/.local/scripts/deadd_notify", NULL}; - -/*First arg only serves to match against key in rules*/ -static const char *scratchpadcmd[] = {"s", "alacritty", "-t", "scratchpad", NULL}; -static const char *sp_emacs[] = {"e", "emacs", "-T", "ScratchEmacs", NULL}; -static const char *sp_volume_control[] = {"v","alacritty", "-t", "sp_volume","-e", "pulsemixer", NULL}; -static const char *tasks[] = {"t","todoist", NULL}; -static const char *pomo[] = {"p","pomodone", NULL}; -static Key keys[] = { - /* modifier key function argument */ - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY|ShiftMask, XK_s, spawn, {.v = flameshot } }, - { MODKEY|Mod1Mask, XK_space, spawn, {.v = deadd_notify } }, - { 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|Mod1Mask, XK_h, incrgaps, {.i = +1 } }, - { MODKEY|Mod1Mask, XK_l, incrgaps, {.i = -10 } }, - { MODKEY|Mod1Mask|ShiftMask, XK_h, incrogaps, {.i = +10 } }, - { MODKEY|Mod1Mask|ShiftMask, XK_l, incrogaps, {.i = -10 } }, - { MODKEY|Mod1Mask|ControlMask, XK_h, incrigaps, {.i = +10 } }, - { MODKEY|Mod1Mask|ControlMask, XK_l, incrigaps, {.i = -10 } }, - { MODKEY|Mod1Mask, XK_0, togglegaps, {0} }, - { MODKEY|Mod1Mask|ShiftMask, XK_0, defaultgaps, {0} }, - { MODKEY, XK_y, incrihgaps, {.i = +10 } }, - { MODKEY, XK_o, incrihgaps, {.i = -10 } }, - { MODKEY|ControlMask, XK_y, incrivgaps, {.i = +10 } }, - { MODKEY|ControlMask, XK_o, incrivgaps, {.i = -10 } }, - { MODKEY|Mod1Mask, XK_y, incrohgaps, {.i = +10 } }, - { MODKEY|Mod1Mask, XK_o, incrohgaps, {.i = -10 } }, - { MODKEY|ShiftMask, XK_y, incrovgaps, {.i = +10 } }, - { MODKEY|ShiftMask, XK_o, incrovgaps, {.i = -10 } }, - { 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|ShiftMask, XK_f, togglefullscr, {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 } }, - { MODKEY, XK_minus, setgaps, {.i = -5 } }, - { MODKEY, XK_equal, setgaps, {.i = +5 } }, - { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, - /*SCRATCHPADS*/ - { MODKEY, XK_u, togglescratch, {.v = scratchpadcmd } }, - { MODKEY|ShiftMask, XK_m, togglescratch, {.v = sp_volume_control } }, - { MODKEY, XK_e, togglescratch, {.v = sp_emacs } }, - { MODKEY|ShiftMask, XK_d, togglescratch, {.v = tasks } }, - { MODKEY|ShiftMask, XK_e, togglescratch, {.v = pomo } }, - { MODKEY, XK_n, togglealttag, {0} }, - TAGKEYS( XK_1, 0) - TAGKEYS( XK_2, 1) - TAGKEYS( XK_3, 2) - TAGKEYS( XK_4, 3) - TAGKEYS( XK_5, 4) - TAGKEYS( XK_6, 5) - TAGKEYS( XK_7, 6) - TAGKEYS( XK_8, 7) - TAGKEYS( XK_9, 8) - { MODKEY|ShiftMask, XK_q, quit, {0} }, -}; - -/* button definitions */ -/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ -static Button buttons[] = { - /* click event mask button function argument */ - { ClkLtSymbol, 0, Button1, setlayout, {0} }, - { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, - { ClkWinTitle, 0, Button2, zoom, {0} }, - { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, - { ClkClientWin, MODKEY, Button1, movemouse, {0} }, - { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, - { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, - { ClkTagBar, 0, Button1, view, {0} }, - { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, -}; - diff --git a/dwm-6.2/config.mk b/dwm-6.2/config.mk deleted file mode 100644 index 7084c33..0000000 --- a/dwm-6.2/config.mk +++ /dev/null @@ -1,38 +0,0 @@ -# dwm version -VERSION = 6.2 - -# 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 - -# includes and libs -INCS = -I${X11INC} -I${FREETYPEINC} -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} - -# flags -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} -CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} -LDFLAGS = ${LIBS} - -# Solaris -#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" -#LDFLAGS = ${LIBS} - -# compiler and linker -CC = cc diff --git a/dwm-6.2/drw.c b/dwm-6.2/drw.c deleted file mode 100644 index 6f71c1a..0000000 --- a/dwm-6.2/drw.c +++ /dev/null @@ -1,433 +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."); - } - - /* Do not allow using color fonts. This is a workaround for a BadLength - * error from Xft with color glyphs. Modelled on the Xterm workaround. See - * https://bugzilla.redhat.com/show_bug.cgi?id=1498269 - * https://lists.suckless.org/dev/1701/30932.html - * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349 - * and lots more all over the internet. - */ - - font = ecalloc(1, sizeof(Fnt)); - font->xfont = xfont; - font->pattern = pattern; - font->h = xfont->ascent + xfont->descent; - font->dpy = drw->dpy; - - return font; -} - -static void -xfont_free(Fnt *font) -{ - if (!font) - return; - if (font->pattern) - FcPatternDestroy(font->pattern); - XftFontClose(font->dpy, font->xfont); - free(font); -} - -Fnt* -drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) -{ - Fnt *cur, *ret = NULL; - size_t i; - - if (!drw || !fonts) - return NULL; - - for (i = 1; i <= fontcount; i++) { - if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) { - cur->next = ret; - ret = cur; - } - } - return (drw->fonts = ret); -} - -void -drw_fontset_free(Fnt *font) -{ - if (font) { - drw_fontset_free(font->next); - xfont_free(font); - } -} - -void -drw_clr_create(Drw *drw, Clr *dest, const char *clrname) -{ - if (!drw || !dest || !clrname) - return; - - if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), - DefaultColormap(drw->dpy, drw->screen), - clrname, dest)) - die("error, cannot allocate color '%s'", clrname); - - dest->pixel |= 0xff << 24; -} - -/* Wrapper to create color schemes. The caller has to call free(3) on the - * returned color scheme when done using it. */ -Clr * -drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) -{ - size_t i; - Clr *ret; - - /* need at least two colors for a scheme */ - if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor)))) - return NULL; - - for (i = 0; i < clrcount; i++) - drw_clr_create(drw, &ret[i], clrnames[i]); - return ret; -} - -void -drw_setfontset(Drw *drw, Fnt *set) -{ - if (drw) - drw->fonts = set; -} - -void -drw_setscheme(Drw *drw, Clr *scm) -{ - if (drw) - drw->scheme = scm; -} - -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) -{ - char buf[1024]; - int ty; - unsigned int ew; - XftDraw *d = NULL; - Fnt *usedfont, *curfont, *nextfont; - size_t i, len; - int utf8strlen, utf8charlen, render = x || y || w || h; - long utf8codepoint = 0; - const char *utf8str; - FcCharSet *fccharset; - FcPattern *fcpattern; - FcPattern *match; - XftResult result; - int charexists = 0; - - if (!drw || (render && !drw->scheme) || !text || !drw->fonts) - return 0; - - if (!render) { - w = ~w; - } else { - XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); - XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); - d = XftDrawCreate(drw->dpy, drw->drawable, - DefaultVisual(drw->dpy, drw->screen), - DefaultColormap(drw->dpy, drw->screen)); - x += lpad; - w -= lpad; - } - - usedfont = drw->fonts; - while (1) { - utf8strlen = 0; - utf8str = text; - nextfont = NULL; - while (*text) { - utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ); - for (curfont = drw->fonts; curfont; curfont = curfont->next) { - charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); - if (charexists) { - if (curfont == usedfont) { - utf8strlen += utf8charlen; - text += utf8charlen; - } else { - nextfont = curfont; - } - break; - } - } - - if (!charexists || nextfont) - break; - else - charexists = 0; - } - - if (utf8strlen) { - drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL); - /* shorten text if necessary */ - for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--) - drw_font_getexts(usedfont, utf8str, len, &ew, NULL); - - if (len) { - memcpy(buf, utf8str, len); - buf[len] = '\0'; - if (len < utf8strlen) - for (i = len; i && i > len - 3; buf[--i] = '.') - ; /* NOP */ - - if (render) { - ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; - XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], - usedfont->xfont, x, ty, (XftChar8 *)buf, len); - } - x += ew; - w -= ew; - } - } - - if (!*text) { - break; - } else if (nextfont) { - charexists = 0; - usedfont = nextfont; - } else { - /* Regardless of whether or not a fallback font is found, the - * character must be drawn. */ - charexists = 1; - - fccharset = FcCharSetCreate(); - FcCharSetAddChar(fccharset, utf8codepoint); - - if (!drw->fonts->pattern) { - /* Refer to the comment in xfont_create for more information. */ - die("the first font in the cache must be loaded from a font string."); - } - - fcpattern = FcPatternDuplicate(drw->fonts->pattern); - FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); - FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); - FcPatternAddBool(fcpattern, FC_COLOR, FcFalse); - - FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); - FcDefaultSubstitute(fcpattern); - match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result); - - FcCharSetDestroy(fccharset); - FcPatternDestroy(fcpattern); - - if (match) { - usedfont = xfont_create(drw, NULL, match); - if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) { - for (curfont = drw->fonts; curfont->next; curfont = curfont->next) - ; /* NOP */ - curfont->next = usedfont; - } else { - xfont_free(usedfont); - usedfont = drw->fonts; - } - } - } - } - if (d) - XftDrawDestroy(d); - - return x + (render ? w : 0); -} - -void -drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) -{ - if (!drw) - return; - - XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); - XSync(drw->dpy, False); -} - -unsigned int -drw_fontset_getwidth(Drw *drw, const char *text) -{ - if (!drw || !drw->fonts || !text) - return 0; - return drw_text(drw, 0, 0, 0, 0, 0, text, 0); -} - -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/dwm-6.2/drw.h b/dwm-6.2/drw.h deleted file mode 100644 index 4bcd5ad..0000000 --- a/dwm-6.2/drw.h +++ /dev/null @@ -1,57 +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); -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/dwm-6.2/dwm b/dwm-6.2/dwm deleted file mode 100755 index 8b3a36769678bc44efe0568ed77bc3a7f752649a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77528 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 -#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, SchemeStatus, SchemeTagsSel, SchemeTagsNorm, SchemeInfoSel, SchemeInfoNorm }; /* 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; - int bw, oldbw; - unsigned int tags; - int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; - char scratchkey; - 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 */ - int gappx; /* gaps between windows */ - int gappih; /* horizontal gap between windows */ - int gappiv; /* vertical gap between windows */ - int gappoh; /* horizontal outer gaps */ - int gappov; /* vertical outer gaps */ - 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]; - unsigned int alttag; -}; - -typedef struct { - const char *class; - const char *instance; - const char *title; - unsigned int tags; - int isfloating; - int monitor; - const char scratchkey; -} Rule; - -typedef struct { - const char** command; - const char* name; -} Launcher; - - -/* function declarations */ -static void applyrules(Client *c); -static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); -static void arrange(Monitor *m); -static void arrangemon(Monitor *m); -static void attach(Client *c); -static void attachstack(Client *c); -static void buttonpress(XEvent *e); -static void checkotherwm(void); -static void cleanup(void); -static void cleanupmon(Monitor *mon); -static void clientmessage(XEvent *e); -static void configure(Client *c); -static void configurenotify(XEvent *e); -static void configurerequest(XEvent *e); -static Monitor *createmon(void); -static void 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 *); -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 runautostart(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 setgaps(int oh, int ov, int ih, int iv); -static void incrgaps(const Arg *arg); -static void incrigaps(const Arg *arg); -static void incrogaps(const Arg *arg); -static void incrohgaps(const Arg *arg); -static void incrovgaps(const Arg *arg); -static void incrihgaps(const Arg *arg); -static void incrivgaps(const Arg *arg); -static void togglegaps(const Arg *arg); -static void defaultgaps(const Arg *arg); -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 sigchld(int unused); -static void spawn(const Arg *arg); -static void spawnscratch(const Arg *arg); -static void tag(const Arg *arg); -static void tagmon(const Arg *arg); -static void tile(Monitor *); -static void togglealttag(); -static void togglebar(const Arg *arg); -static void togglefloating(const Arg *arg); -static void togglefullscr(const Arg *arg); -static void togglescratch(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); -static void autostart_exec(void); - -/* variables */ -static const char autostartblocksh[] = "autostart_blocking.sh"; -static const char autostartsh[] = "autostart.sh"; -static const char broken[] = "broken"; -static const char dwmdir[] = "dwm"; -static const char localshare[] = ".local/share"; -static char stext[256]; -static int screen; -static int sw, sh; /* X display screen geometry width, height */ -static int bh, blw = 0; /* bar geometry */ -static int enablegaps = 1; /* enables gaps, used by togglegaps */ -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]; }; - -/* dwm will keep pid's of processes from autostart array and kill them at quit */ -static pid_t *autostart_pids; -static size_t autostart_len; - -/* execute command from autostart array */ -static void -autostart_exec() { - const char *const *p; - size_t i = 0; - - /* count entries */ - for (p = autostart; *p; autostart_len++, p++) - while (*++p); - - autostart_pids = malloc(autostart_len * sizeof(pid_t)); - for (p = autostart; *p; i++, p++) { - if ((autostart_pids[i] = fork()) == 0) { - setsid(); - execvp(*p, (char *const *)p); - fprintf(stderr, "dwm: execvp %s\n", *p); - perror(" failed"); - _exit(EXIT_FAILURE); - } - /* skip arguments */ - while (*++p); - } -} - -/* 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; - c->scratchkey = 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; - c->scratchkey = r->scratchkey; - 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) { - /* 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; - goto execute_handler; - } else if (ev->x < x + blw) { - click = ClkLtSymbol; - goto execute_handler; - } - - x += blw; - - for(i = 0; i < LENGTH(launchers); i++) { - x += TEXTW(launchers[i].name); - - if (ev->x < x) { - Arg a; - a.v = launchers[i].command; - spawn(&a); - return; - } - } - - if (ev->x > selmon->ww - TEXTW(stext)) - click = ClkStatusText; - else - click = ClkWinTitle; - } else if ((c = wintoclient(ev->window))) { - focus(c); - restack(selmon); - XAllowEvents(dpy, ReplayPointer, CurrentTime); - click = ClkClientWin; - } - - execute_handler: - - for (i = 0; i < LENGTH(buttons); i++) - if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button - && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) - buttons[i].func(click == ClkTagBar && 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]); - 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 */)); - } 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; - 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) { - 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->gappx = gappx; - m->gappih = gappih; - m->gappiv = gappiv; - m->gappoh = gappoh; - m->gappov = gappov; - 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, wdelta, sw, tw = 0; - int boxs = drw->fonts->h / 9; - int boxw = drw->fonts->h / 6 + 2; - unsigned int i, occ = 0, urg = 0; - Client *c; - - /* 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[SchemeStatus]); - 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]); - wdelta = selmon->alttag ? abs(TEXTW(tags[i]) - TEXTW(tagsalt[i])) / 2 : 0; - drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeTagsSel : SchemeTagsNorm]); - drw_text(drw, x, 0, w, bh, wdelta + lrpad / 2, (selmon->alttag ? tagsalt[i] : 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 = blw = TEXTW(m->ltsymbol); - drw_setscheme(drw, scheme[SchemeNorm]); - x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); - - for (i = 0; i < LENGTH(launchers); i++) - { - w = TEXTW(launchers[i].name); - drw_text(drw, x, 0, w, bh, lrpad / 2, launchers[i].name, urg & 1 << i); - x += w; - } - - if ((w = m->ww - tw - x) > bh) { - if (m->sel) { - /* fix overflow when window name is bigger than window width */ - int mid = (m->ww - (int)TEXTW(m->sel->name)) / 2 - x; - /* make sure name will not overlap on tags even when it is very long */ - mid = mid >= lrpad / 2 ? mid : lrpad / 2; - drw_setscheme(drw, scheme[m == selmon ? SchemeInfoSel : SchemeInfoNorm]); - drw_text(drw, x, 0, w, bh, mid, 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[SchemeInfoNorm]); - 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) - 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; - unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; - KeyCode code; - - XUngrabKey(dpy, AnyKey, AnyModifier, root); - for (i = 0; i < LENGTH(keys); i++) - if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) - for (j = 0; j < LENGTH(modifiers); j++) - XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, - True, GrabModeAsync, GrabModeAsync); - } -} - -void -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->mx + c->mon->mw) - c->x = c->mon->mx + c->mon->mw - WIDTH(c); - if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh) - c->y = c->mon->my + c->mon->mh - HEIGHT(c); - c->x = MAX(c->x, c->mon->mx); - /* only fix client y-offset, if the client center might cover the bar */ - c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx) - && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); - c->bw = borderpx; - - wc.border_width = c->bw; - if (((nexttiled(c->mon->clients) == c && !nexttiled(c->next)) - || &monocle == c->mon->lt[c->mon->sellt]->arrange)) - { - c->w = wc.width += c->bw * 2; - c->h = wc.height += c->bw * 2; - wc.border_width = 0; - } - 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); - c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2; - c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2; - XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); - grabbuttons(c, 0); - if (!c->isfloating) - c->isfloating = c->oldstate = trans != None || c->isfixed; - if (c->isfloating) - XRaiseWindow(dpy, c->win); - attach(c); - attachstack(c); - XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, - (unsigned char *) &(c->win), 1); - XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ - 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)) - return; - if (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; - 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: - updatesizehints(c); - 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 -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; - if (((nexttiled(c->mon->clients) == c && !nexttiled(c->next)) - || &monocle == c->mon->lt[c->mon->sellt]->arrange) - && !c->isfullscreen && !c->isfloating) { - c->w = wc.width += c->bw * 2; - c->h = wc.height += c->bw * 2; - wc.border_width = 0; - } - 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; - 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 -runautostart(void) -{ - char *pathpfx; - char *path; - char *xdgdatahome; - char *home; - struct stat sb; - - if ((home = getenv("HOME")) == NULL) - /* this is almost impossible */ - return; - - /* if $XDG_DATA_HOME is set and not empty, use $XDG_DATA_HOME/dwm, - * otherwise use ~/.local/share/dwm as autostart script directory - */ - xdgdatahome = getenv("XDG_DATA_HOME"); - if (xdgdatahome != NULL && *xdgdatahome != '\0') { - /* space for path segments, separators and nul */ - pathpfx = ecalloc(1, strlen(xdgdatahome) + strlen(dwmdir) + 2); - - if (sprintf(pathpfx, "%s/%s", xdgdatahome, dwmdir) <= 0) { - free(pathpfx); - return; - } - } else { - /* space for path segments, separators and nul */ - pathpfx = ecalloc(1, strlen(home) + strlen(localshare) - + strlen(dwmdir) + 3); - - if (sprintf(pathpfx, "%s/%s/%s", home, localshare, dwmdir) < 0) { - free(pathpfx); - return; - } - } - - /* check if the autostart script directory exists */ - if (! (stat(pathpfx, &sb) == 0 && S_ISDIR(sb.st_mode))) { - /* the XDG conformant path does not exist or is no directory - * so we try ~/.dwm instead - */ - char *pathpfx_new = realloc(pathpfx, strlen(home) + strlen(dwmdir) + 3); - if(pathpfx_new == NULL) { - free(pathpfx); - return; - } - pathpfx = pathpfx_new; - - if (sprintf(pathpfx, "%s/.%s", home, dwmdir) <= 0) { - free(pathpfx); - return; - } - } - - /* try the blocking script first */ - path = ecalloc(1, strlen(pathpfx) + strlen(autostartblocksh) + 2); - if (sprintf(path, "%s/%s", pathpfx, autostartblocksh) <= 0) { - free(path); - free(pathpfx); - } - - if (access(path, X_OK) == 0) - system(path); - - /* now the non-blocking script */ - if (sprintf(path, "%s/%s", pathpfx, autostartsh) <= 0) { - free(path); - free(pathpfx); - } - - if (access(path, X_OK) == 0) - system(strcat(path, " &")); - - free(pathpfx); - free(path); -} - -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; - } else if (!fullscreen && c->isfullscreen){ - XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, - PropModeReplace, (unsigned char*)0, 0); - c->isfullscreen = 0; - } -} -void -setgaps(int oh, int ov, int ih, int iv) -{ - if (oh < 0) oh = 0; - if (ov < 0) ov = 0; - if (ih < 0) ih = 0; - if (iv < 0) iv = 0; - - selmon->gappoh = oh; - selmon->gappov = ov; - selmon->gappih = ih; - selmon->gappiv = iv; - arrange(selmon); -} - -void -togglegaps(const Arg *arg) -{ - enablegaps = !enablegaps; - arrange(selmon); -} - -void -defaultgaps(const Arg *arg) -{ - setgaps(gappoh, gappov, gappih, gappiv); -} - -void -incrgaps(const Arg *arg) -{ - setgaps( - selmon->gappoh + arg->i, - selmon->gappov + arg->i, - selmon->gappih + arg->i, - selmon->gappiv + arg->i - ); -} - -void -incrigaps(const Arg *arg) -{ - setgaps( - selmon->gappoh, - selmon->gappov, - selmon->gappih + arg->i, - selmon->gappiv + arg->i - ); -} - -void -incrogaps(const Arg *arg) -{ - setgaps( - selmon->gappoh + arg->i, - selmon->gappov + arg->i, - selmon->gappih, - selmon->gappiv - ); -} - -void -incrohgaps(const Arg *arg) -{ - setgaps( - selmon->gappoh + arg->i, - selmon->gappov, - selmon->gappih, - selmon->gappiv - ); -} - -void -incrovgaps(const Arg *arg) -{ - setgaps( - selmon->gappoh, - selmon->gappov + arg->i, - selmon->gappih, - selmon->gappiv - ); -} - -void -incrihgaps(const Arg *arg) -{ - setgaps( - selmon->gappoh, - selmon->gappov, - selmon->gappih + arg->i, - selmon->gappiv - ); -} - -void -incrivgaps(const Arg *arg) -{ - setgaps( - selmon->gappoh, - selmon->gappov, - selmon->gappih, - selmon->gappiv + arg->i - ); -} - -void -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; - - /* clean up any zombies immediately */ - sigchld(0); - - /* init screen */ - screen = DefaultScreen(dpy); - sw = DisplayWidth(dpy, screen); - sh = DisplayHeight(dpy, screen); - root = RootWindow(dpy, screen); - drw = drw_create(dpy, screen, root, sw, sh); - if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) - die("no fonts could be loaded."); - lrpad = drw->fonts->h; - bh = drw->fonts->h + 2; - 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 -togglealttag() -{ - selmon->alttag = !selmon->alttag; - drawbar(selmon); -} - - -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) - 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 -sigchld(int unused) -{ - pid_t pid; - - if (signal(SIGCHLD, sigchld) == SIG_ERR) - die("can't install SIGCHLD handler:"); - 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 -spawn(const Arg *arg) -{ - if (arg->v == dmenucmd) - dmenumon[0] = '0' + selmon->num; - if (fork() == 0) { - if (dpy) - close(ConnectionNumber(dpy)); - setsid(); - execvp(((char **)arg->v)[0], (char **)arg->v); - fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]); - perror(" failed"); - exit(EXIT_SUCCESS); - } -} - -void spawnscratch(const Arg *arg) -{ - if (fork() == 0) { - if (dpy) - close(ConnectionNumber(dpy)); - setsid(); - execvp(((char **)arg->v)[1], ((char **)arg->v)+1); - fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[1]); - perror(" failed"); - exit(EXIT_SUCCESS); - } -} - - -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, r, oe = enablegaps, ie = enablegaps, mw, my, ty; - Client *c; - - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - if (n == 0) - return; - - if (smartgaps == n) { - oe = 0; // outer gaps disabled - } - -if (n > m->nmaster) - mw = m->nmaster ? (m->ww + m->gappiv*ie) * m->mfact : 0; - else - mw = m->ww - 2*m->gappov*oe + m->gappiv*ie; - for (i = 0, my = ty = m->gappoh*oe, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if (i < m->nmaster) { - r = MIN(n, m->nmaster) - i; - h = (m->wh - my - m->gappoh*oe - m->gappih*ie * (r - 1)) / r; - resize(c, m->wx + m->gappov*oe, m->wy + my, mw - (2*c->bw) - m->gappiv*ie, h - (2*c->bw), 0); - if (my + HEIGHT(c) + m->gappih*ie < m->wh) - my += HEIGHT(c) + m->gappih*ie; - } else { - r = n - i; - h = (m->wh - ty - m->gappoh*oe - m->gappih*ie * (r - 1)) / r; - resize(c, m->wx + mw + m->gappov*oe, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappov*oe, h - (2*c->bw), 0); - if (ty + HEIGHT(c) + m->gappih*ie < m->wh) - ty += HEIGHT(c) + m->gappih*ie; - } - } - - -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; - 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 -togglescratch(const Arg *arg) -{ - Client *c; - unsigned int found = 0; - - for (c = selmon->clients; c && !(found = c->scratchkey == ((char**)arg->v)[0][0]); c = c->next); - if (found) { - c->tags = ISVISIBLE(c) ? 0 : selmon->tagset[selmon->seltags]; - focus(NULL); - arrange(selmon); - - if (ISVISIBLE(c)) { - focus(c); - restack(selmon); - } - - } else{ - spawnscratch(arg); - } -} - -void -togglefullscr(const Arg *arg) -{ - if(selmon->sel) - setfullscreen(selmon->sel, !selmon->sel->isfullscreen); -} - -void -toggletag(const Arg *arg) -{ - unsigned int newtags; - - if (!selmon->sel) - return; - newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); - if (newtags) { - selmon->sel->tags = newtags; - 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); - 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() -{ - 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; - if (n <= nn) { /* new monitors available */ - for (i = 0; i < (nn - n); i++) { - for (m = mons; m && m->next; m = m->next); - if (m) - m->next = createmon(); - else - mons = createmon(); - } - for (i = 0, m = mons; i < nn && m; m = m->next, i++) - if (i >= n - || unique[i].x_org != m->mx || unique[i].y_org != m->my - || unique[i].width != m->mw || unique[i].height != m->mh) - { - dirty = 1; - m->num = i; - m->mx = m->wx = unique[i].x_org; - m->my = m->wy = unique[i].y_org; - m->mw = m->ww = unique[i].width; - m->mh = m->wh = unique[i].height; - updatebarpos(m); - } - } else { /* less monitors available nn < n */ - for (i = nn; i < n; i++) { - for (m = mons; m && m->next; m = m->next); - while ((c = m->clients)) { - dirty = 1; - m->clients = c->next; - detachstack(c); - c->mon = mons; - attach(c); - 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); -} - -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 - || (selmon->sel && selmon->sel->isfloating)) - return; - if (c == nexttiled(selmon->clients)) - if (!c || !(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(); - runautostart(); - run(); - cleanup(); - XCloseDisplay(dpy); - return EXIT_SUCCESS; -} diff --git a/dwm-6.2/dwm.c.orig b/dwm-6.2/dwm.c.orig deleted file mode 100644 index dade245..0000000 --- a/dwm-6.2/dwm.c.orig +++ /dev/null @@ -1,2404 +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 -#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, SchemeStatus, SchemeTagsSel, SchemeTagsNorm, SchemeInfoSel, SchemeInfoNorm }; /* 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; - int bw, oldbw; - unsigned int tags; - int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; - char scratchkey; - 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 */ - int gappx; /* gaps between windows */ - 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]; - unsigned int alttag; -}; - -typedef struct { - const char *class; - const char *instance; - const char *title; - unsigned int tags; - int isfloating; - int monitor; - const char scratchkey; -} Rule; - -typedef struct { - const char** command; - const char* name; -} Launcher; - - -/* function declarations */ -static void applyrules(Client *c); -static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); -static void arrange(Monitor *m); -static void arrangemon(Monitor *m); -static void attach(Client *c); -static void attachstack(Client *c); -static void buttonpress(XEvent *e); -static void checkotherwm(void); -static void cleanup(void); -static void cleanupmon(Monitor *mon); -static void clientmessage(XEvent *e); -static void configure(Client *c); -static void configurenotify(XEvent *e); -static void configurerequest(XEvent *e); -static Monitor *createmon(void); -static void 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 *); -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 runautostart(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 setgaps(const Arg *arg); -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 sigchld(int unused); -static void spawn(const Arg *arg); -static void spawnscratch(const Arg *arg); -static void tag(const Arg *arg); -static void tagmon(const Arg *arg); -static void tile(Monitor *); -static void togglealttag(); -static void togglebar(const Arg *arg); -static void togglefloating(const Arg *arg); -static void togglefullscr(const Arg *arg); -static void togglescratch(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); -static void autostart_exec(void); - -/* variables */ -static const char autostartblocksh[] = "autostart_blocking.sh"; -static const char autostartsh[] = "autostart.sh"; -static const char broken[] = "broken"; -static const char dwmdir[] = "dwm"; -static const char localshare[] = ".local/share"; -static char stext[256]; -static int screen; -static int sw, sh; /* X display screen geometry width, height */ -static int bh, blw = 0; /* bar geometry */ -static int lrpad; /* sum of left and right padding for text */ -static int (*xerrorxlib)(Display *, XErrorEvent *); -static unsigned int numlockmask = 0; -static void (*handler[LASTEvent]) (XEvent *) = { - [ButtonPress] = buttonpress, - [ClientMessage] = clientmessage, - [ConfigureRequest] = configurerequest, - [ConfigureNotify] = configurenotify, - [DestroyNotify] = destroynotify, - [EnterNotify] = enternotify, - [Expose] = expose, - [FocusIn] = focusin, - [KeyPress] = keypress, - [MappingNotify] = mappingnotify, - [MapRequest] = maprequest, - [MotionNotify] = motionnotify, - [PropertyNotify] = propertynotify, - [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]; }; - -/* dwm will keep pid's of processes from autostart array and kill them at quit */ -static pid_t *autostart_pids; -static size_t autostart_len; - -/* execute command from autostart array */ -static void -autostart_exec() { - const char *const *p; - size_t i = 0; - - /* count entries */ - for (p = autostart; *p; autostart_len++, p++) - while (*++p); - - autostart_pids = malloc(autostart_len * sizeof(pid_t)); - for (p = autostart; *p; i++, p++) { - if ((autostart_pids[i] = fork()) == 0) { - setsid(); - execvp(*p, (char *const *)p); - fprintf(stderr, "dwm: execvp %s\n", *p); - perror(" failed"); - _exit(EXIT_FAILURE); - } - /* skip arguments */ - while (*++p); - } -} - -/* 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; - c->scratchkey = 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; - c->scratchkey = r->scratchkey; - 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) { - /* 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; - goto execute_handler; - } else if (ev->x < x + blw) { - click = ClkLtSymbol; - goto execute_handler; - } - - x += blw; - - for(i = 0; i < LENGTH(launchers); i++) { - x += TEXTW(launchers[i].name); - - if (ev->x < x) { - Arg a; - a.v = launchers[i].command; - spawn(&a); - return; - } - } - - if (ev->x > selmon->ww - TEXTW(stext)) - click = ClkStatusText; - else - click = ClkWinTitle; - } else if ((c = wintoclient(ev->window))) { - focus(c); - restack(selmon); - XAllowEvents(dpy, ReplayPointer, CurrentTime); - click = ClkClientWin; - } - - execute_handler: - - for (i = 0; i < LENGTH(buttons); i++) - if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button - && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) - buttons[i].func(click == ClkTagBar && 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]); - 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 */)); - } 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; - 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) { - 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->gappx = gappx; - 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, wdelta, sw, tw = 0; - int boxs = drw->fonts->h / 9; - int boxw = drw->fonts->h / 6 + 2; - unsigned int i, occ = 0, urg = 0; - Client *c; - - /* 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[SchemeStatus]); - 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]); - wdelta = selmon->alttag ? abs(TEXTW(tags[i]) - TEXTW(tagsalt[i])) / 2 : 0; - drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeTagsSel : SchemeTagsNorm]); - drw_text(drw, x, 0, w, bh, wdelta + lrpad / 2, (selmon->alttag ? tagsalt[i] : 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 = blw = TEXTW(m->ltsymbol); - drw_setscheme(drw, scheme[SchemeNorm]); - x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); - - for (i = 0; i < LENGTH(launchers); i++) - { - w = TEXTW(launchers[i].name); - drw_text(drw, x, 0, w, bh, lrpad / 2, launchers[i].name, urg & 1 << i); - x += w; - } - - if ((w = m->ww - tw - x) > bh) { - if (m->sel) { - /* fix overflow when window name is bigger than window width */ - int mid = (m->ww - (int)TEXTW(m->sel->name)) / 2 - x; - /* make sure name will not overlap on tags even when it is very long */ - mid = mid >= lrpad / 2 ? mid : lrpad / 2; - drw_setscheme(drw, scheme[m == selmon ? SchemeInfoSel : SchemeInfoNorm]); - drw_text(drw, x, 0, w, bh, mid, 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[SchemeInfoNorm]); - 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) - 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; - unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; - KeyCode code; - - XUngrabKey(dpy, AnyKey, AnyModifier, root); - for (i = 0; i < LENGTH(keys); i++) - if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) - for (j = 0; j < LENGTH(modifiers); j++) - XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, - True, GrabModeAsync, GrabModeAsync); - } -} - -void -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->mx + c->mon->mw) - c->x = c->mon->mx + c->mon->mw - WIDTH(c); - if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh) - c->y = c->mon->my + c->mon->mh - HEIGHT(c); - c->x = MAX(c->x, c->mon->mx); - /* only fix client y-offset, if the client center might cover the bar */ - c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx) - && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); - c->bw = borderpx; - - wc.border_width = c->bw; - if (((nexttiled(c->mon->clients) == c && !nexttiled(c->next)) - || &monocle == c->mon->lt[c->mon->sellt]->arrange)) - { - c->w = wc.width += c->bw * 2; - c->h = wc.height += c->bw * 2; - wc.border_width = 0; - } - 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); - c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2; - c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2; - XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); - grabbuttons(c, 0); - if (!c->isfloating) - c->isfloating = c->oldstate = trans != None || c->isfixed; - if (c->isfloating) - XRaiseWindow(dpy, c->win); - attach(c); - attachstack(c); - XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, - (unsigned char *) &(c->win), 1); - XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ - 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)) - return; - if (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; - 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: - updatesizehints(c); - 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 -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; - if (((nexttiled(c->mon->clients) == c && !nexttiled(c->next)) - || &monocle == c->mon->lt[c->mon->sellt]->arrange) - && !c->isfullscreen && !c->isfloating) { - c->w = wc.width += c->bw * 2; - c->h = wc.height += c->bw * 2; - wc.border_width = 0; - } - 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; - 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 -runautostart(void) -{ - char *pathpfx; - char *path; - char *xdgdatahome; - char *home; - struct stat sb; - - if ((home = getenv("HOME")) == NULL) - /* this is almost impossible */ - return; - - /* if $XDG_DATA_HOME is set and not empty, use $XDG_DATA_HOME/dwm, - * otherwise use ~/.local/share/dwm as autostart script directory - */ - xdgdatahome = getenv("XDG_DATA_HOME"); - if (xdgdatahome != NULL && *xdgdatahome != '\0') { - /* space for path segments, separators and nul */ - pathpfx = ecalloc(1, strlen(xdgdatahome) + strlen(dwmdir) + 2); - - if (sprintf(pathpfx, "%s/%s", xdgdatahome, dwmdir) <= 0) { - free(pathpfx); - return; - } - } else { - /* space for path segments, separators and nul */ - pathpfx = ecalloc(1, strlen(home) + strlen(localshare) - + strlen(dwmdir) + 3); - - if (sprintf(pathpfx, "%s/%s/%s", home, localshare, dwmdir) < 0) { - free(pathpfx); - return; - } - } - - /* check if the autostart script directory exists */ - if (! (stat(pathpfx, &sb) == 0 && S_ISDIR(sb.st_mode))) { - /* the XDG conformant path does not exist or is no directory - * so we try ~/.dwm instead - */ - char *pathpfx_new = realloc(pathpfx, strlen(home) + strlen(dwmdir) + 3); - if(pathpfx_new == NULL) { - free(pathpfx); - return; - } - pathpfx = pathpfx_new; - - if (sprintf(pathpfx, "%s/.%s", home, dwmdir) <= 0) { - free(pathpfx); - return; - } - } - - /* try the blocking script first */ - path = ecalloc(1, strlen(pathpfx) + strlen(autostartblocksh) + 2); - if (sprintf(path, "%s/%s", pathpfx, autostartblocksh) <= 0) { - free(path); - free(pathpfx); - } - - if (access(path, X_OK) == 0) - system(path); - - /* now the non-blocking script */ - if (sprintf(path, "%s/%s", pathpfx, autostartsh) <= 0) { - free(path); - free(pathpfx); - } - - if (access(path, X_OK) == 0) - system(strcat(path, " &")); - - free(pathpfx); - free(path); -} - -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; - } else if (!fullscreen && c->isfullscreen){ - XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, - PropModeReplace, (unsigned char*)0, 0); - c->isfullscreen = 0; - } -} - -void -setgaps(const Arg *arg) -{ - if ((arg->i == 0) || (selmon->gappx + arg->i < 0)) - selmon->gappx = 0; - else - selmon->gappx += arg->i; - arrange(selmon); -} - -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; - - /* clean up any zombies immediately */ - sigchld(0); - - /* init screen */ - screen = DefaultScreen(dpy); - sw = DisplayWidth(dpy, screen); - sh = DisplayHeight(dpy, screen); - root = RootWindow(dpy, screen); - drw = drw_create(dpy, screen, root, sw, sh); - if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) - die("no fonts could be loaded."); - lrpad = drw->fonts->h; - bh = drw->fonts->h + 2; - 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 -togglealttag() -{ - selmon->alttag = !selmon->alttag; - drawbar(selmon); -} - - -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) - 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 -sigchld(int unused) -{ - pid_t pid; - - if (signal(SIGCHLD, sigchld) == SIG_ERR) - die("can't install SIGCHLD handler:"); - 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 -spawn(const Arg *arg) -{ - if (arg->v == dmenucmd) - dmenumon[0] = '0' + selmon->num; - if (fork() == 0) { - if (dpy) - close(ConnectionNumber(dpy)); - setsid(); - execvp(((char **)arg->v)[0], (char **)arg->v); - fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]); - perror(" failed"); - exit(EXIT_SUCCESS); - } -} - -void spawnscratch(const Arg *arg) -{ - if (fork() == 0) { - if (dpy) - close(ConnectionNumber(dpy)); - setsid(); - execvp(((char **)arg->v)[1], ((char **)arg->v)+1); - fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[1]); - perror(" failed"); - exit(EXIT_SUCCESS); - } -} - - -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, ns; - Client *c; - - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - if (n == 0) - return; - if(n == 1){ - c = nexttiled(m->clients); - resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); - return; - } - - if (n > m->nmaster){ - mw = m->nmaster ? m->ww * m->mfact : 0; - ns = m->nmaster > 0 ? 2 : 1; - } - else{ - mw = m->ww - m->gappx; - ns = 1; - } - for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if (i < m->nmaster) { - h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx; - resize(c, m->wx + m->gappx, m->wy + my, mw - 2*c->bw - m->gappx*(5-ns)/2, h - 2*c->bw, 0); - if(my + HEIGHT(c) + m->gappx < m->wh) - my += HEIGHT(c) + m->gappx; - } else { - h = (m->wh - ty) / (n - i) - m->gappx; - resize(c, m->wx + mw + m->gappx/ns, m->wy + ty, m->ww - mw - (2*c->bw) - m->gappx*(5-ns)/2, h - 2*c->bw, 0); - if(ty + HEIGHT(c) + m->gappx < m->wh) - ty += HEIGHT(c) + m->gappx; - } -} - -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; - 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 -togglescratch(const Arg *arg) -{ - Client *c; - unsigned int found = 0; - - for (c = selmon->clients; c && !(found = c->scratchkey == ((char**)arg->v)[0][0]); c = c->next); - if (found) { - c->tags = ISVISIBLE(c) ? 0 : selmon->tagset[selmon->seltags]; - focus(NULL); - arrange(selmon); - - if (ISVISIBLE(c)) { - focus(c); - restack(selmon); - } - - } else{ - spawnscratch(arg); - } -} - -void -togglefullscr(const Arg *arg) -{ - if(selmon->sel) - setfullscreen(selmon->sel, !selmon->sel->isfullscreen); -} - -void -toggletag(const Arg *arg) -{ - unsigned int newtags; - - if (!selmon->sel) - return; - newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); - if (newtags) { - selmon->sel->tags = newtags; - 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); - 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() -{ - 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; - if (n <= nn) { /* new monitors available */ - for (i = 0; i < (nn - n); i++) { - for (m = mons; m && m->next; m = m->next); - if (m) - m->next = createmon(); - else - mons = createmon(); - } - for (i = 0, m = mons; i < nn && m; m = m->next, i++) - if (i >= n - || unique[i].x_org != m->mx || unique[i].y_org != m->my - || unique[i].width != m->mw || unique[i].height != m->mh) - { - dirty = 1; - m->num = i; - m->mx = m->wx = unique[i].x_org; - m->my = m->wy = unique[i].y_org; - m->mw = m->ww = unique[i].width; - m->mh = m->wh = unique[i].height; - updatebarpos(m); - } - } else { /* less monitors available nn < n */ - for (i = nn; i < n; i++) { - for (m = mons; m && m->next; m = m->next); - while ((c = m->clients)) { - dirty = 1; - m->clients = c->next; - detachstack(c); - c->mon = mons; - attach(c); - 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); -} - -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 - || (selmon->sel && selmon->sel->isfloating)) - return; - if (c == nexttiled(selmon->clients)) - if (!c || !(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(); - runautostart(); - run(); - cleanup(); - XCloseDisplay(dpy); - return EXIT_SUCCESS; -} diff --git a/dwm-6.2/dwm.c.rej b/dwm-6.2/dwm.c.rej deleted file mode 100644 index f605fee..0000000 --- a/dwm-6.2/dwm.c.rej +++ /dev/null @@ -1,88 +0,0 @@ ---- dwm.c -+++ dwm.c -@@ -119,6 +119,10 @@ struct Monitor { - int by; /* bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ -+ int gappih; /* horizontal gap between windows */ -+ int gappiv; /* vertical gap between windows */ -+ int gappoh; /* horizontal outer gaps */ -+ int gappov; /* vertical outer gaps */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; -@@ -200,6 +204,16 @@ 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 setgaps(int oh, int ov, int ih, int iv); -+static void incrgaps(const Arg *arg); -+static void incrigaps(const Arg *arg); -+static void incrogaps(const Arg *arg); -+static void incrohgaps(const Arg *arg); -+static void incrovgaps(const Arg *arg); -+static void incrihgaps(const Arg *arg); -+static void incrivgaps(const Arg *arg); -+static void togglegaps(const Arg *arg); -+static void defaultgaps(const Arg *arg); - static void setlayout(const Arg *arg); - static void setmfact(const Arg *arg); - static void setup(void); -@@ -640,6 +655,10 @@ createmon(void) - m->nmaster = nmaster; - m->showbar = showbar; - m->topbar = topbar; -+ m->gappih = gappih; -+ m->gappiv = gappiv; -+ m->gappoh = gappoh; -+ m->gappov = gappov; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -@@ -1780,28 +1904,34 @@ tagmon(const Arg *arg) - void - tile(Monitor *m) - { -- unsigned int i, n, h, mw, my, ty; -+ unsigned int i, n, h, r, oe = enablegaps, ie = enablegaps, mw, my, ty; - Client *c; - - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - if (n == 0) - return; - -+ if (smartgaps == n) { -+ oe = 0; // outer gaps disabled -+ } -+ - if (n > m->nmaster) -- mw = m->nmaster ? m->ww * m->mfact : 0; -+ mw = m->nmaster ? (m->ww + m->gappiv*ie) * m->mfact : 0; - else -- mw = m->ww; -- for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) -+ mw = m->ww - 2*m->gappov*oe + m->gappiv*ie; -+ for (i = 0, my = ty = m->gappoh*oe, 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); -+ r = MIN(n, m->nmaster) - i; -+ h = (m->wh - my - m->gappoh*oe - m->gappih*ie * (r - 1)) / r; -+ resize(c, m->wx + m->gappov*oe, m->wy + my, mw - (2*c->bw) - m->gappiv*ie, h - (2*c->bw), 0); -+ if (my + HEIGHT(c) + m->gappih*ie < m->wh) -+ my += HEIGHT(c) + m->gappih*ie; - } 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); -+ r = n - i; -+ h = (m->wh - ty - m->gappoh*oe - m->gappih*ie * (r - 1)) / r; -+ resize(c, m->wx + mw + m->gappov*oe, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappov*oe, h - (2*c->bw), 0); -+ if (ty + HEIGHT(c) + m->gappih*ie < m->wh) -+ ty += HEIGHT(c) + m->gappih*ie; - } - } - diff --git a/dwm-6.2/dwm.png b/dwm-6.2/dwm.png deleted file mode 100644 index b1f9ba7e5f4cc7350ee2392ebcea5fcbe00fb49b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 373 zcmeAS@N?(olHy`uVBq!ia0vp^2Y@($g9*gC@m3f}u_bxCyDx`7I;J! zGca%iWx0hJ8D`Cq01C2~c>21sUt<^MF=V?Ztt9{yk}YwKC~?lu%}vcKVQ?-=O)N=G zQ7F$W$xsN%NL6t6^bL5QqM8R(c+=CxF{I+w+q;fj4F)_6j>`Z3pZ>_($QEQ&92OXP z%lpEKGwG8$G-U1H{@Y%;mx-mNK|p|siBVAj$Z~Mt-~h6K0!}~{PyozQ07(f5fTdVi zm=-zT`NweeJ#%S&{fequZGmkDDC*%x$$Sa*fAP=$`nJkhx1Y~k<8b2;Hq)FOdV=P$ q&oWzoxz_&nv&n0)xBzV8k*jsxheTIy&cCY600f?{elF{r5}E*x)opSB diff --git a/dwm-6.2/patches/dwm-actualfullscreen-20191112-cb3f58a.diff b/dwm-6.2/patches/dwm-actualfullscreen-20191112-cb3f58a.diff deleted file mode 100644 index 21eea19..0000000 --- a/dwm-6.2/patches/dwm-actualfullscreen-20191112-cb3f58a.diff +++ /dev/null @@ -1,53 +0,0 @@ -From 3a16816a6f5d38014c2a06ce395873c545c8789a Mon Sep 17 00:00:00 2001 -From: Soenke Lambert -Date: Tue, 12 Nov 2019 10:44:02 +0100 -Subject: [PATCH] Fullscreen current window with [Alt]+[Shift]+[f] - -This actually fullscreens a window, instead of just hiding the statusbar -and applying the monocle layout. ---- - config.def.h | 1 + - dwm.c | 8 ++++++++ - 2 files changed, 9 insertions(+) - -diff --git a/config.def.h b/config.def.h -index 1c0b587..8cd3204 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -78,6 +78,7 @@ static Key keys[] = { - { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, - { MODKEY, XK_space, setlayout, {0} }, - { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, -+ { MODKEY|ShiftMask, XK_f, togglefullscr, {0} }, - { MODKEY, XK_0, view, {.ui = ~0 } }, - { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, - { MODKEY, XK_comma, focusmon, {.i = -1 } }, -diff --git a/dwm.c b/dwm.c -index 4465af1..c1b899a 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -211,6 +211,7 @@ static void tagmon(const Arg *arg); - static void tile(Monitor *); - static void togglebar(const Arg *arg); - static void togglefloating(const Arg *arg); -+static void togglefullscr(const Arg *arg); - static void toggletag(const Arg *arg); - static void toggleview(const Arg *arg); - static void unfocus(Client *c, int setfocus); -@@ -1719,6 +1720,13 @@ togglefloating(const Arg *arg) - arrange(selmon); - } - -+void -+togglefullscr(const Arg *arg) -+{ -+ if(selmon->sel) -+ setfullscreen(selmon->sel, !selmon->sel->isfullscreen); -+} -+ - void - toggletag(const Arg *arg) - { --- -2.17.1 - diff --git a/dwm-6.2/patches/dwm-alternativetags-6.2.diff b/dwm-6.2/patches/dwm-alternativetags-6.2.diff deleted file mode 100644 index dc6a0cf..0000000 --- a/dwm-6.2/patches/dwm-alternativetags-6.2.diff +++ /dev/null @@ -1,93 +0,0 @@ -From 25aa44b5998a2aac840a0eecf9d8a479695b2577 Mon Sep 17 00:00:00 2001 -From: Piyush Pangtey -Date: Sat, 13 Apr 2019 00:24:23 +0530 -Subject: [PATCH] alternative tags - -Having icons as tags sure makes dwm look awesome, but having tags number -simplifies tags related operations. This patch introduces alternative -tags which can be switched on the fly for the sole purpose of providing -visual aid. - -Signed-off-by: Piyush Pangtey ---- - config.def.h | 2 ++ - dwm.c | 14 ++++++++++++-- - 2 files changed, 14 insertions(+), 2 deletions(-) - -diff --git a/config.def.h b/config.def.h -index 1c0b587..e6c2565 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -20,6 +20,7 @@ static const char *colors[][3] = { - - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; -+static const char *tagsalt[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - - static const Rule rules[] = { - /* xprop(1): -@@ -84,6 +85,7 @@ static Key keys[] = { - { MODKEY, XK_period, focusmon, {.i = +1 } }, - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, - { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, -+ { MODKEY, XK_n, togglealttag, {0} }, - TAGKEYS( XK_1, 0) - TAGKEYS( XK_2, 1) - TAGKEYS( XK_3, 2) -diff --git a/dwm.c b/dwm.c -index 4465af1..ee292e1 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -130,6 +130,7 @@ struct Monitor { - Monitor *next; - Window barwin; - const Layout *lt[2]; -+ unsigned int alttag; - }; - - typedef struct { -@@ -209,6 +210,7 @@ static void spawn(const Arg *arg); - static void tag(const Arg *arg); - static void tagmon(const Arg *arg); - static void tile(Monitor *); -+static void togglealttag(); - static void togglebar(const Arg *arg); - static void togglefloating(const Arg *arg); - static void toggletag(const Arg *arg); -@@ -695,7 +697,7 @@ dirtomon(int dir) - void - drawbar(Monitor *m) - { -- int x, w, sw = 0; -+ int x, w, wdelta, sw = 0; - int boxs = drw->fonts->h / 9; - int boxw = drw->fonts->h / 6 + 2; - unsigned int i, occ = 0, urg = 0; -@@ -716,8 +718,9 @@ drawbar(Monitor *m) - x = 0; - for (i = 0; i < LENGTH(tags); i++) { - w = TEXTW(tags[i]); -+ wdelta = selmon->alttag ? abs(TEXTW(tags[i]) - TEXTW(tagsalt[i])) / 2 : 0; - 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); -+ drw_text(drw, x, 0, w, bh, wdelta + lrpad / 2, (selmon->alttag ? tagsalt[i] : 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, -@@ -1696,6 +1699,13 @@ tile(Monitor *m) - } - } - -+void -+togglealttag() -+{ -+ selmon->alttag = !selmon->alttag; -+ drawbar(selmon); -+} -+ - void - togglebar(const Arg *arg) - { --- -2.21.0 - diff --git a/dwm-6.2/patches/dwm-alwayscenter-20200625-f04cac6.diff b/dwm-6.2/patches/dwm-alwayscenter-20200625-f04cac6.diff deleted file mode 100644 index 03ea9ef..0000000 --- a/dwm-6.2/patches/dwm-alwayscenter-20200625-f04cac6.diff +++ /dev/null @@ -1,12 +0,0 @@ -diff -up dwm/dwm.c dwmmod/dwm.c ---- dwm/dwm.c 2020-06-25 00:21:30.383692180 -0300 -+++ dwmmod/dwm.c 2020-06-25 00:20:35.643692330 -0300 -@@ -1057,6 +1057,8 @@ manage(Window w, XWindowAttributes *wa) - updatewindowtype(c); - updatesizehints(c); - updatewmhints(c); -+ c->x = c->mon->mx + (c->mon->mw - WIDTH(c)) / 2; -+ c->y = c->mon->my + (c->mon->mh - HEIGHT(c)) / 2; - XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); - grabbuttons(c, 0); - if (!c->isfloating) diff --git a/dwm-6.2/patches/dwm-autostart-20161205-bb3bd6f.diff b/dwm-6.2/patches/dwm-autostart-20161205-bb3bd6f.diff deleted file mode 100644 index 6f11eaf..0000000 --- a/dwm-6.2/patches/dwm-autostart-20161205-bb3bd6f.diff +++ /dev/null @@ -1,39 +0,0 @@ -commit 5918623c5bd7fda155bf9dc3d33890c4ae1722d0 -Author: Simon Bremer -Date: Thu Dec 22 17:31:07 2016 +0100 - - Applied and fixed autostart patch for previous version; - -diff --git a/dwm.c b/dwm.c -index d27cb67..066ed71 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -194,6 +194,7 @@ 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 runAutostart(void); - static void scan(void); - static int sendevent(Client *c, Atom proto); - static void sendmon(Client *c, Monitor *m); -@@ -1386,6 +1387,12 @@ run(void) - } - - void -+runAutostart(void) { -+ system("cd ~/.dwm; ./autostart_blocking.sh"); -+ system("cd ~/.dwm; ./autostart.sh &"); -+} -+ -+void - scan(void) - { - unsigned int i, num; -@@ -2145,6 +2152,7 @@ main(int argc, char *argv[]) - checkotherwm(); - setup(); - scan(); -+ runAutostart(); - run(); - cleanup(); - XCloseDisplay(dpy); diff --git a/dwm-6.2/patches/dwm-autostart-20200610-cb3f58a.diff b/dwm-6.2/patches/dwm-autostart-20200610-cb3f58a.diff deleted file mode 100644 index 7e17424..0000000 --- a/dwm-6.2/patches/dwm-autostart-20200610-cb3f58a.diff +++ /dev/null @@ -1,179 +0,0 @@ -From 37e970479dc5d40e57fc0cbfeaa5e39941483237 Mon Sep 17 00:00:00 2001 -From: Gan Ainm -Date: Wed, 10 Jun 2020 10:59:02 +0000 -Subject: [PATCH] dwm-xdgautostart-6.2.diff - -=================================================================== ---- - dwm.1 | 23 +++++++++++++++++ - dwm.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 105 insertions(+) - -diff --git a/dwm.1 b/dwm.1 -index 13b3729..9533aa6 100644 ---- a/dwm.1 -+++ b/dwm.1 -@@ -30,6 +30,14 @@ top left corner. The tags which are applied to one or more windows are - indicated with an empty square in the top left corner. - .P - dwm draws a small border around windows to indicate the focus state. -+.P -+On start, dwm can start additional programs that may be specified in two special -+shell scripts (see the FILES section below), autostart_blocking.sh and -+autostart.sh. The former is executed first and dwm will wait for its -+termination before starting. The latter is executed in the background before -+dwm enters its handler loop. -+.P -+Either of these files may be omitted. - .SH OPTIONS - .TP - .B \-v -@@ -152,6 +160,21 @@ Toggles focused window between floating and tiled state. - .TP - .B Mod1\-Button3 - Resize focused window while dragging. Tiled windows will be toggled to the floating state. -+.SH FILES -+The files containing programs to be started along with dwm are searched for in -+the following directories: -+.IP "1. $XDG_DATA_HOME/dwm" -+.IP "2. $HOME/.local/share/dwm" -+.IP "3. $HOME/.dwm" -+.P -+The first existing directory is scanned for any of the autostart files below. -+.TP 15 -+autostart.sh -+This file is started as a shell background process before dwm enters its handler -+loop. -+.TP 15 -+autostart_blocking.sh -+This file is started before any autostart.sh; dwm waits for its termination. - .SH CUSTOMIZATION - dwm is customized by creating a custom config.h and (re)compiling the source - code. This keeps it fast, secure and simple. -diff --git a/dwm.c b/dwm.c -index 4465af1..2156b49 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -193,6 +194,7 @@ 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 runautostart(void); - static void scan(void); - static int sendevent(Client *c, Atom proto); - static void sendmon(Client *c, Monitor *m); -@@ -235,7 +237,11 @@ static int xerrorstart(Display *dpy, XErrorEvent *ee); - static void zoom(const Arg *arg); - - /* variables */ -+static const char autostartblocksh[] = "autostart_blocking.sh"; -+static const char autostartsh[] = "autostart.sh"; - static const char broken[] = "broken"; -+static const char dwmdir[] = "dwm"; -+static const char localshare[] = ".local/share"; - static char stext[256]; - static int screen; - static int sw, sh; /* X display screen geometry width, height */ -@@ -1380,6 +1386,83 @@ run(void) - handler[ev.type](&ev); /* call handler */ - } - -+void -+runautostart(void) -+{ -+ char *pathpfx; -+ char *path; -+ char *xdgdatahome; -+ char *home; -+ struct stat sb; -+ -+ if ((home = getenv("HOME")) == NULL) -+ /* this is almost impossible */ -+ return; -+ -+ /* if $XDG_DATA_HOME is set and not empty, use $XDG_DATA_HOME/dwm, -+ * otherwise use ~/.local/share/dwm as autostart script directory -+ */ -+ xdgdatahome = getenv("XDG_DATA_HOME"); -+ if (xdgdatahome != NULL && *xdgdatahome != '\0') { -+ /* space for path segments, separators and nul */ -+ pathpfx = ecalloc(1, strlen(xdgdatahome) + strlen(dwmdir) + 2); -+ -+ if (sprintf(pathpfx, "%s/%s", xdgdatahome, dwmdir) <= 0) { -+ free(pathpfx); -+ return; -+ } -+ } else { -+ /* space for path segments, separators and nul */ -+ pathpfx = ecalloc(1, strlen(home) + strlen(localshare) -+ + strlen(dwmdir) + 3); -+ -+ if (sprintf(pathpfx, "%s/%s/%s", home, localshare, dwmdir) < 0) { -+ free(pathpfx); -+ return; -+ } -+ } -+ -+ /* check if the autostart script directory exists */ -+ if (! (stat(pathpfx, &sb) == 0 && S_ISDIR(sb.st_mode))) { -+ /* the XDG conformant path does not exist or is no directory -+ * so we try ~/.dwm instead -+ */ -+ char *pathpfx_new = realloc(pathpfx, strlen(home) + strlen(dwmdir) + 3); -+ if(pathpfx_new == NULL) { -+ free(pathpfx); -+ return; -+ } -+ pathpfx = pathpfx_new; -+ -+ if (sprintf(pathpfx, "%s/.%s", home, dwmdir) <= 0) { -+ free(pathpfx); -+ return; -+ } -+ } -+ -+ /* try the blocking script first */ -+ path = ecalloc(1, strlen(pathpfx) + strlen(autostartblocksh) + 2); -+ if (sprintf(path, "%s/%s", pathpfx, autostartblocksh) <= 0) { -+ free(path); -+ free(pathpfx); -+ } -+ -+ if (access(path, X_OK) == 0) -+ system(path); -+ -+ /* now the non-blocking script */ -+ if (sprintf(path, "%s/%s", pathpfx, autostartsh) <= 0) { -+ free(path); -+ free(pathpfx); -+ } -+ -+ if (access(path, X_OK) == 0) -+ system(strcat(path, " &")); -+ -+ free(pathpfx); -+ free(path); -+} -+ - void - scan(void) - { -@@ -2142,6 +2223,7 @@ main(int argc, char *argv[]) - die("pledge"); - #endif /* __OpenBSD__ */ - scan(); -+ runautostart(); - run(); - cleanup(); - XCloseDisplay(dpy); --- -2.27.0 - diff --git a/dwm-6.2/patches/dwm-centeredwindowname-20200723-f035e1e.diff b/dwm-6.2/patches/dwm-centeredwindowname-20200723-f035e1e.diff deleted file mode 100644 index 67ae4d3..0000000 --- a/dwm-6.2/patches/dwm-centeredwindowname-20200723-f035e1e.diff +++ /dev/null @@ -1,30 +0,0 @@ -From f035e1e5abb19df5dced9c592ca986deac460435 Mon Sep 17 00:00:00 2001 -From: bastila <20937049+silentfault@users.noreply.github.com> -Date: Thu, 23 Jul 2020 02:45:12 +0300 -Subject: [PATCH] Fix overflow when window name is bigger than window width - ---- - dwm.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/dwm.c b/dwm.c -index 9fd0286..42cb8dd 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -731,8 +731,12 @@ drawbar(Monitor *m) - - if ((w = m->ww - tw - x) > bh) { - if (m->sel) { -+ /* fix overflow when window name is bigger than window width */ -+ int mid = (m->ww - (int)TEXTW(m->sel->name)) / 2 - x; -+ /* make sure name will not overlap on tags even when it is very long */ -+ mid = mid >= lrpad / 2 ? mid : lrpad / 2; - drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); -- drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); -+ drw_text(drw, x, 0, w, bh, mid, m->sel->name, 0); - if (m->sel->isfloating) - drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); - } else { --- -2.27.0 - diff --git a/dwm-6.2/patches/dwm-cool-autostart-6.2.diff b/dwm-6.2/patches/dwm-cool-autostart-6.2.diff deleted file mode 100644 index 84a93ea..0000000 --- a/dwm-6.2/patches/dwm-cool-autostart-6.2.diff +++ /dev/null @@ -1,116 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 1c0b587..ed056a4 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -18,6 +18,11 @@ static const char *colors[][3] = { - [SchemeSel] = { col_gray4, col_cyan, col_cyan }, - }; - -+static const char *const autostart[] = { -+ "st", NULL, -+ NULL /* terminate */ -+}; -+ - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - -diff --git a/dwm.c b/dwm.c -index 9fd0286..1facd56 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -234,6 +234,7 @@ 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 const char broken[] = "broken"; -@@ -275,6 +276,34 @@ static Window root, wmcheckwin; - /* 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; -+ size_t i = 0; -+ -+ /* count entries */ -+ for (p = autostart; *p; autostart_len++, p++) -+ while (*++p); -+ -+ autostart_pids = malloc(autostart_len * sizeof(pid_t)); -+ for (p = autostart; *p; i++, p++) { -+ if ((autostart_pids[i] = fork()) == 0) { -+ setsid(); -+ execvp(*p, (char *const *)p); -+ fprintf(stderr, "dwm: execvp %s\n", *p); -+ perror(" failed"); -+ _exit(EXIT_FAILURE); -+ } -+ /* skip arguments */ -+ while (*++p); -+ } -+} -+ - /* function implementations */ - void - applyrules(Client *c) -@@ -1249,6 +1278,16 @@ propertynotify(XEvent *e) - 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; - } - -@@ -1632,9 +1671,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 -@@ -2139,6 +2194,7 @@ main(int argc, char *argv[]) - if (!(dpy = XOpenDisplay(NULL))) - die("dwm: cannot open display"); - checkotherwm(); -+ autostart_exec(); - setup(); - #ifdef __OpenBSD__ - if (pledge("stdio rpath proc exec", NULL) == -1) - diff --git a/dwm-6.2/patches/dwm-fakefullscreen-20170508-ceac8c9.diff b/dwm-6.2/patches/dwm-fakefullscreen-20170508-ceac8c9.diff deleted file mode 100644 index 0c15db4..0000000 --- a/dwm-6.2/patches/dwm-fakefullscreen-20170508-ceac8c9.diff +++ /dev/null @@ -1,92 +0,0 @@ -diff --git a/dwm.c b/dwm.c -index a5ce993..42d2049 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -522,7 +522,7 @@ clientmessage(XEvent *e) - 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))); -+ || cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */)); - } else if (cme->message_type == netatom[NetActiveWindow]) { - if (c != selmon->sel && !c->isurgent) - seturgent(c, 1); -@@ -552,7 +552,6 @@ void - configurenotify(XEvent *e) - { - Monitor *m; -- Client *c; - XConfigureEvent *ev = &e->xconfigure; - int dirty; - -@@ -565,9 +564,6 @@ configurenotify(XEvent *e) - 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); -@@ -1145,8 +1141,6 @@ movemouse(const Arg *arg) - - if (!(c = selmon->sel)) - return; -- if (c->isfullscreen) /* no support moving fullscreen windows by mouse */ -- return; - restack(selmon); - ocx = c->x; - ocy = c->y; -@@ -1300,8 +1294,6 @@ resizemouse(const Arg *arg) - - if (!(c = selmon->sel)) - return; -- if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */ -- return; - restack(selmon); - ocx = c->x; - ocy = c->y; -@@ -1478,24 +1470,10 @@ setfullscreen(Client *c, int fullscreen) - 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); - } - } - -@@ -1620,7 +1598,7 @@ showhide(Client *c) - 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) -+ if (!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) - resize(c, c->x, c->y, c->w, c->h, 0); - showhide(c->snext); - } else { -@@ -1712,8 +1690,6 @@ 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, diff --git a/dwm-6.2/patches/dwm-floatrules-6.2.diff b/dwm-6.2/patches/dwm-floatrules-6.2.diff deleted file mode 100644 index 5dab1e0..0000000 --- a/dwm-6.2/patches/dwm-floatrules-6.2.diff +++ /dev/null @@ -1,64 +0,0 @@ -diff -u dwm/config.def.h dwmnew/config.def.h ---- dwm/config.def.h 2020-03-01 19:10:06.676821764 +1300 -+++ dwmnew/config.def.h 2020-03-01 19:29:26.276901430 +1300 -@@ -26,9 +26,9 @@ - * 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 }, -+ /* class instance title tags mask isfloating monitor float x,y,w,h floatborderpx*/ -+ { "Gimp", NULL, NULL, 0, 1, -1, 50,50,500,500, 5 }, -+ { "Firefox", NULL, NULL, 1 << 8, 0, -1, 50,50,500,500, 5 }, - }; - - /* layout(s) */ -Only in dwmnew: config.h -Only in dwmnew: drw.o -diff -u dwm/dwm.c dwmnew/dwm.c ---- dwm/dwm.c 2020-03-01 19:10:06.680155097 +1300 -+++ dwmnew/dwm.c 2020-03-01 19:28:26.793564016 +1300 -@@ -93,6 +93,7 @@ - int bw, oldbw; - unsigned int tags; - int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; -+ int floatborderpx; - Client *next; - Client *snext; - Monitor *mon; -@@ -139,6 +140,8 @@ - unsigned int tags; - int isfloating; - int monitor; -+ int floatx, floaty, floatw, floath; -+ int floatborderpx; - } Rule; - - /* function declarations */ -@@ -299,6 +302,13 @@ - { - c->isfloating = r->isfloating; - c->tags |= r->tags; -+ c->floatborderpx = r->floatborderpx; -+ if (r->isfloating) { -+ c->x = r->floatx; -+ c->y = r->floaty; -+ c->w = r->floatw; -+ c->h = r->floath; -+ } - for (m = mons; m && m->num != r->monitor; m = m->next); - if (m) - c->mon = m; -@@ -1281,7 +1291,10 @@ - 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; -+ if (c->isfloating) -+ wc.border_width = c->floatborderpx; -+ else -+ wc.border_width = c->bw; - XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); - configure(c); - XSync(dpy, False); diff --git a/dwm-6.2/patches/dwm-fullscreen-6.2.diff b/dwm-6.2/patches/dwm-fullscreen-6.2.diff deleted file mode 100644 index 36e3140..0000000 --- a/dwm-6.2/patches/dwm-fullscreen-6.2.diff +++ /dev/null @@ -1,56 +0,0 @@ -From 54719285bd1a984e2efce6e8a8eab184fec11abf Mon Sep 17 00:00:00 2001 -From: Sermak -Date: Mon, 8 Jul 2019 01:06:44 +0200 -Subject: [PATCH] Simulate toggleable fullscreen mode - ---- - config.def.h | 1 + - dwm.c | 14 ++++++++++++++ - 2 files changed, 15 insertions(+) - -diff --git a/config.def.h b/config.def.h -index 1c0b587..f774cc5 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -76,6 +76,7 @@ static Key keys[] = { - { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, - { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, - { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, -+ { MODKEY|ShiftMask, XK_f, fullscreen, {0} }, - { MODKEY, XK_space, setlayout, {0} }, - { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, - { MODKEY, XK_0, view, {.ui = ~0 } }, -diff --git a/dwm.c b/dwm.c -index 4465af1..04b1e06 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -199,6 +199,7 @@ 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 fullscreen(const Arg *arg); - static void setlayout(const Arg *arg); - static void setmfact(const Arg *arg); - static void setup(void); -@@ -1497,6 +1498,19 @@ setfullscreen(Client *c, int fullscreen) - } - } - -+Layout *last_layout; -+void -+fullscreen(const Arg *arg) -+{ -+ if (selmon->showbar) { -+ for(last_layout = (Layout *)layouts; last_layout != selmon->lt[selmon->sellt]; last_layout++); -+ setlayout(&((Arg) { .v = &layouts[2] })); -+ } else { -+ setlayout(&((Arg) { .v = last_layout })); -+ } -+ togglebar(arg); -+} -+ - void - setlayout(const Arg *arg) - { --- -2.22.0 diff --git a/dwm-6.2/patches/dwm-gaps-6.0.diff b/dwm-6.2/patches/dwm-gaps-6.0.diff deleted file mode 100644 index 80e1c8d..0000000 --- a/dwm-6.2/patches/dwm-gaps-6.0.diff +++ /dev/null @@ -1,53 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 77ff358..a4e496b 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -9,6 +9,7 @@ static const char selbordercolor[] = "#005577"; - static const char selbgcolor[] = "#005577"; - static const char selfgcolor[] = "#eeeeee"; - static const unsigned int borderpx = 1; /* border pixel of windows */ -+static const unsigned int gappx = 1; /* gap pixel between windows */ - static const unsigned int snap = 32; /* snap pixel */ - static const Bool showbar = True; /* False means no bar */ - static const Bool topbar = True; /* False means bottom bar */ -diff --git a/dwm.c b/dwm.c -index 1d78655..6cc96ff 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -1703,7 +1703,7 @@ textnw(const char *text, unsigned int len) { - - void - tile(Monitor *m) { -- unsigned int i, n, h, mw, my, ty; -+ unsigned int i, n, h, r, g = 0, mw, my, ty; - Client *c; - - for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -@@ -1711,19 +1711,21 @@ tile(Monitor *m) { - return; - - if(n > m->nmaster) -- mw = m->nmaster ? m->ww * m->mfact : 0; -+ mw = m->nmaster ? (m->ww - (g = gappx)) * 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); -+ r = MIN(n, m->nmaster) - i; -+ h = (m->wh - my - gappx * (r - 1)) / r; - resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), False); -- my += HEIGHT(c); -+ my += HEIGHT(c) + gappx; - } - 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), False); -- ty += HEIGHT(c); -+ r = n - i; -+ h = (m->wh - ty - gappx * (r - 1)) / r; -+ resize(c, m->wx + mw + g, m->wy + ty, m->ww - mw - g - (2*c->bw), h - (2*c->bw), False); -+ ty += HEIGHT(c) + gappx; - } - } - diff --git a/dwm-6.2/patches/dwm-launchers-20200527-f09418b.diff b/dwm-6.2/patches/dwm-launchers-20200527-f09418b.diff deleted file mode 100644 index a683636..0000000 --- a/dwm-6.2/patches/dwm-launchers-20200527-f09418b.diff +++ /dev/null @@ -1,101 +0,0 @@ -From 6b5e23cdf8108a9033acc7c21c8926c0c72647fc Mon Sep 17 00:00:00 2001 -From: Adham Zahran -Date: Wed, 27 May 2020 18:07:57 +0200 -Subject: [PATCH] Top bar now has buttons that launches programs - ---- - config.def.h | 8 ++++++++ - dwm.c | 36 ++++++++++++++++++++++++++++++++++-- - 2 files changed, 42 insertions(+), 2 deletions(-) - -diff --git a/config.def.h b/config.def.h -index 1c0b587..9231cd5 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -21,6 +21,14 @@ static const char *colors[][3] = { - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - -+/* launcher commands (They must be NULL terminated) */ -+static const char* surf[] = { "surf", "duckduckgo.com", NULL }; -+ -+static const Launcher launchers[] = { -+ /* command name to display */ -+ { surf, "surf" }, -+}; -+ - static const Rule rules[] = { - /* xprop(1): - * WM_CLASS(STRING) = instance, class -diff --git a/dwm.c b/dwm.c -index 9fd0286..79e7e20 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -141,6 +141,11 @@ typedef struct { - int monitor; - } Rule; - -+typedef struct { -+ const char** command; -+ const char* name; -+} Launcher; -+ - /* function declarations */ - static void applyrules(Client *c); - static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); -@@ -438,9 +443,26 @@ buttonpress(XEvent *e) - if (i < LENGTH(tags)) { - click = ClkTagBar; - arg.ui = 1 << i; -- } else if (ev->x < x + blw) -+ goto execute_handler; -+ } else if (ev->x < x + blw) { - click = ClkLtSymbol; -- else if (ev->x > selmon->ww - TEXTW(stext)) -+ goto execute_handler; -+ } -+ -+ x += blw; -+ -+ for(i = 0; i < LENGTH(launchers); i++) { -+ x += TEXTW(launchers[i].name); -+ -+ if (ev->x < x) { -+ Arg a; -+ a.v = launchers[i].command; -+ spawn(&a); -+ return; -+ } -+ } -+ -+ if (ev->x > selmon->ww - TEXTW(stext)) - click = ClkStatusText; - else - click = ClkWinTitle; -@@ -450,6 +472,9 @@ buttonpress(XEvent *e) - XAllowEvents(dpy, ReplayPointer, CurrentTime); - click = ClkClientWin; - } -+ -+execute_handler: -+ - for (i = 0; i < LENGTH(buttons); i++) - if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button - && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) -@@ -728,6 +753,13 @@ drawbar(Monitor *m) - w = blw = TEXTW(m->ltsymbol); - drw_setscheme(drw, scheme[SchemeNorm]); - x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); -+ -+ for (i = 0; i < LENGTH(launchers); i++) -+ { -+ w = TEXTW(launchers[i].name); -+ drw_text(drw, x, 0, w, bh, lrpad / 2, launchers[i].name, urg & 1 << i); -+ x += w; -+ } - - if ((w = m->ww - tw - x) > bh) { - if (m->sel) { --- -2.17.1 - diff --git a/dwm-6.2/patches/dwm-namedscratchpads-6.2.diff b/dwm-6.2/patches/dwm-namedscratchpads-6.2.diff deleted file mode 100644 index d007118..0000000 --- a/dwm-6.2/patches/dwm-namedscratchpads-6.2.diff +++ /dev/null @@ -1,138 +0,0 @@ -diff '--color=auto' -up dwm-6.2/config.def.h dwm-6.2-new/config.def.h ---- dwm-6.2/config.def.h 2019-02-02 12:55:28.000000000 +0000 -+++ dwm-6.2-new/config.def.h 2020-04-26 13:51:06.713332746 +0100 -@@ -26,9 +26,10 @@ static const Rule rules[] = { - * 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 }, -+ /* class instance title tags mask isfloating monitor scratch key */ -+ { "Gimp", NULL, NULL, 0, 1, -1, 0 }, -+ { "firefox", NULL, NULL, 1 << 8, 0, -1, 0 }, -+ { NULL, NULL, "scratchpad", 0, 1, -1, 's' }, - }; - - /* layout(s) */ -@@ -59,10 +60,14 @@ static char dmenumon[2] = "0"; /* compon - 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 }; - -+/*First arg only serves to match against key in rules*/ -+static const char *scratchpadcmd[] = {"s", "st", "-t", "scratchpad", NULL}; -+ - static Key keys[] = { - /* modifier key function argument */ - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, -+ { MODKEY, XK_grave, togglescratch, {.v = scratchpadcmd } }, - { MODKEY, XK_b, togglebar, {0} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, -diff '--color=auto' -up dwm-6.2/dwm.c dwm-6.2-new/dwm.c ---- dwm-6.2/dwm.c 2019-02-02 12:55:28.000000000 +0000 -+++ dwm-6.2-new/dwm.c 2020-04-26 13:55:56.820584361 +0100 -@@ -93,6 +93,7 @@ struct Client { - int bw, oldbw; - unsigned int tags; - int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; -+ char scratchkey; - Client *next; - Client *snext; - Monitor *mon; -@@ -139,6 +140,7 @@ typedef struct { - unsigned int tags; - int isfloating; - int monitor; -+ const char scratchkey; - } Rule; - - /* function declarations */ -@@ -206,11 +208,13 @@ static void seturgent(Client *c, int urg - static void showhide(Client *c); - static void sigchld(int unused); - static void spawn(const Arg *arg); -+static void spawnscratch(const Arg *arg); - static void tag(const Arg *arg); - static void tagmon(const Arg *arg); - static void tile(Monitor *); - static void togglebar(const Arg *arg); - static void togglefloating(const Arg *arg); -+static void togglescratch(const Arg *arg); - static void toggletag(const Arg *arg); - static void toggleview(const Arg *arg); - static void unfocus(Client *c, int setfocus); -@@ -287,6 +291,7 @@ applyrules(Client *c) - /* rule matching */ - c->isfloating = 0; - c->tags = 0; -+ c->scratchkey = 0; - XGetClassHint(dpy, c->win, &ch); - class = ch.res_class ? ch.res_class : broken; - instance = ch.res_name ? ch.res_name : broken; -@@ -299,6 +304,7 @@ applyrules(Client *c) - { - c->isfloating = r->isfloating; - c->tags |= r->tags; -+ c->scratchkey = r->scratchkey; - for (m = mons; m && m->num != r->monitor; m = m->next); - if (m) - c->mon = m; -@@ -308,6 +314,7 @@ applyrules(Client *c) - 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]; - } - -@@ -1652,6 +1659,19 @@ spawn(const Arg *arg) - } - } - -+void spawnscratch(const Arg *arg) -+{ -+ if (fork() == 0) { -+ if (dpy) -+ close(ConnectionNumber(dpy)); -+ setsid(); -+ execvp(((char **)arg->v)[1], ((char **)arg->v)+1); -+ fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[1]); -+ perror(" failed"); -+ exit(EXIT_SUCCESS); -+ } -+} -+ - void - tag(const Arg *arg) - { -@@ -1720,6 +1740,28 @@ togglefloating(const Arg *arg) - } - - void -+togglescratch(const Arg *arg) -+{ -+ Client *c; -+ unsigned int found = 0; -+ -+ for (c = selmon->clients; c && !(found = c->scratchkey == ((char**)arg->v)[0][0]); c = c->next); -+ if (found) { -+ c->tags = ISVISIBLE(c) ? 0 : selmon->tagset[selmon->seltags]; -+ focus(NULL); -+ arrange(selmon); -+ -+ if (ISVISIBLE(c)) { -+ focus(c); -+ restack(selmon); -+ } -+ -+ } else{ -+ spawnscratch(arg); -+ } -+} -+ -+void - toggletag(const Arg *arg) - { - unsigned int newtags; diff --git a/dwm-6.2/patches/dwm-noborder-6.2.diff b/dwm-6.2/patches/dwm-noborder-6.2.diff deleted file mode 100644 index f381eb8..0000000 --- a/dwm-6.2/patches/dwm-noborder-6.2.diff +++ /dev/null @@ -1,30 +0,0 @@ -From 9102fdb9c670218373bbe83c891c8e8138d6a6f4 Mon Sep 17 00:00:00 2001 -From: redacted -Date: Tue, 23 Apr 2019 00:39:27 +0100 -Subject: [PATCH] added noborder patch - ---- - dwm.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/dwm.c b/dwm.c -index 4465af1..685eca1 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -1282,6 +1282,13 @@ resizeclient(Client *c, int x, int y, int w, int h) - c->oldw = c->w; c->w = wc.width = w; - c->oldh = c->h; c->h = wc.height = h; - wc.border_width = c->bw; -+ if (((nexttiled(c->mon->clients) == c && !nexttiled(c->next)) -+ || &monocle == c->mon->lt[c->mon->sellt]->arrange) -+ && !c->isfullscreen && !c->isfloating) { -+ c->w = wc.width += c->bw * 2; -+ c->h = wc.height += c->bw * 2; -+ wc.border_width = 0; -+ } - XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); - configure(c); - XSync(dpy, False); --- -2.21.0 - diff --git a/dwm-6.2/patches/dwm-ru_gaps-6.2.diff b/dwm-6.2/patches/dwm-ru_gaps-6.2.diff deleted file mode 100644 index 61f25f5..0000000 --- a/dwm-6.2/patches/dwm-ru_gaps-6.2.diff +++ /dev/null @@ -1,127 +0,0 @@ -diff -up a/config.def.h b/config.def.h ---- a/config.def.h 2020-04-17 13:37:50.926942626 +0200 -+++ b/config.def.h 2020-04-25 15:24:56.722215722 +0200 -@@ -2,6 +2,7 @@ - - /* appearance */ - static const unsigned int borderpx = 1; /* border pixel of windows */ -+static const int gappx = 5; /* gaps between 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 */ -@@ -84,6 +85,9 @@ static Key keys[] = { - { MODKEY, XK_period, focusmon, {.i = +1 } }, - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, - { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, -+ { MODKEY, XK_minus, setgaps, {.i = -5 } }, -+ { MODKEY, XK_equal, setgaps, {.i = +5 } }, -+ { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, - TAGKEYS( XK_1, 0) - TAGKEYS( XK_2, 1) - TAGKEYS( XK_3, 2) -diff -up a/dwm.c b/dwm.c ---- a/dwm.c 2020-04-17 13:37:50.926942626 +0200 -+++ b/dwm.c 2020-04-25 15:29:37.664175514 +0200 -@@ -119,6 +119,7 @@ struct Monitor { - int by; /* bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ -+ int gappx; /* gaps between windows */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; -@@ -199,6 +200,7 @@ static void sendmon(Client *c, Monitor * - static void setclientstate(Client *c, long state); - static void setfocus(Client *c); - static void setfullscreen(Client *c, int fullscreen); -+static void setgaps(const Arg *arg); - static void setlayout(const Arg *arg); - static void setmfact(const Arg *arg); - static void setup(void); -@@ -638,6 +640,7 @@ createmon(void) - m->nmaster = nmaster; - m->showbar = showbar; - m->topbar = topbar; -+ m->gappx = gappx; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -@@ -1282,6 +1285,13 @@ resizeclient(Client *c, int x, int y, in - c->oldw = c->w; c->w = wc.width = w; - c->oldh = c->h; c->h = wc.height = h; - wc.border_width = c->bw; -+ if (((nexttiled(c->mon->clients) == c && !nexttiled(c->next)) -+ || &monocle == c->mon->lt[c->mon->sellt]->arrange)) -+ { -+ c->w = wc.width += c->bw * 2; -+ c->h = wc.height += c->bw * 2; -+ wc.border_width = 0; -+ } - XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); - configure(c); - XSync(dpy, False); -@@ -1498,6 +1508,16 @@ setfullscreen(Client *c, int fullscreen) - } - - void -+setgaps(const Arg *arg) -+{ -+ if ((arg->i == 0) || (selmon->gappx + arg->i < 0)) -+ selmon->gappx = 0; -+ else -+ selmon->gappx += arg->i; -+ arrange(selmon); -+} -+ -+void - setlayout(const Arg *arg) - { - if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) -@@ -1673,26 +1693,37 @@ tagmon(const Arg *arg) - void - tile(Monitor *m) - { -- unsigned int i, n, h, mw, my, ty; -+ unsigned int i, n, h, mw, my, ty, ns; - Client *c; - - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - if (n == 0) - return; -+ if(n == 1){ -+ c = nexttiled(m->clients); -+ resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); -+ return; -+ } - -- if (n > m->nmaster) -+ 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++) -+ ns = m->nmaster > 0 ? 2 : 1; -+ } -+ else{ -+ mw = m->ww - m->gappx; -+ ns = 1; -+ } -+ for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if (i < m->nmaster) { -- h = (m->wh - my) / (MIN(n, m->nmaster) - i); -- resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); -- my += HEIGHT(c); -+ h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx; -+ resize(c, m->wx + m->gappx, m->wy + my, mw - 2*c->bw - m->gappx*(5-ns)/2, h - 2*c->bw, 0); -+ if(my + HEIGHT(c) + m->gappx < m->wh) -+ my += HEIGHT(c) + m->gappx; - } else { -- h = (m->wh - ty) / (n - i); -- resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); -- ty += HEIGHT(c); -+ h = (m->wh - ty) / (n - i) - m->gappx; -+ resize(c, m->wx + mw + m->gappx/ns, m->wy + ty, m->ww - mw - (2*c->bw) - m->gappx*(5-ns)/2, h - 2*c->bw, 0); -+ if(ty + HEIGHT(c) + m->gappx < m->wh) -+ ty += HEIGHT(c) + m->gappx; - } - } diff --git a/dwm-6.2/patches/dwm-smartborders-6.2.diff b/dwm-6.2/patches/dwm-smartborders-6.2.diff deleted file mode 100644 index 1ff246f..0000000 --- a/dwm-6.2/patches/dwm-smartborders-6.2.diff +++ /dev/null @@ -1,225 +0,0 @@ -diff --git a/dwm.c b/dwm.c -index 4465af1..3c94e4b 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -143,7 +143,7 @@ typedef struct { - - /* function declarations */ - static void applyrules(Client *c); --static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); -+static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int *bw, int interact); - static void arrange(Monitor *m); - static void arrangemon(Monitor *m); - static void attach(Client *c); -@@ -188,8 +188,8 @@ static void pop(Client *); - 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 resize(Client *c, int x, int y, int w, int h, int bw, int interact); -+static void resizeclient(Client *c, int x, int y, int w, int h, int bw); - static void resizemouse(const Arg *arg); - static void restack(Monitor *m); - static void run(void); -@@ -312,7 +312,7 @@ applyrules(Client *c) - } - - int --applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact) -+applysizehints(Client *c, int *x, int *y, int *w, int *h, int *bw, int interact) - { - int baseismin; - Monitor *m = c->mon; -@@ -325,18 +325,18 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact) - *x = sw - WIDTH(c); - if (*y > sh) - *y = sh - HEIGHT(c); -- if (*x + *w + 2 * c->bw < 0) -+ if (*x + *w + 2 * *bw < 0) - *x = 0; -- if (*y + *h + 2 * c->bw < 0) -+ if (*y + *h + 2 * *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) -+ if (*x + *w + 2 * *bw <= m->wx) - *x = m->wx; -- if (*y + *h + 2 * c->bw <= m->wy) -+ if (*y + *h + 2 * *bw <= m->wy) - *y = m->wy; - } - if (*h < bh) -@@ -374,7 +374,7 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact) - if (c->maxh) - *h = MIN(*h, c->maxh); - } -- return *x != c->x || *y != c->y || *w != c->w || *h != c->h; -+ return *x != c->x || *y != c->y || *w != c->w || *h != c->h || *bw != c->bw; - } - - void -@@ -394,9 +394,16 @@ arrange(Monitor *m) - void - arrangemon(Monitor *m) - { -+ Client *c; -+ - strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); - if (m->lt[m->sellt]->arrange) - m->lt[m->sellt]->arrange(m); -+ else -+ /* <>< case; rather than providing an arrange function and upsetting other logic that tests for its presence, simply add borders here */ -+ for (c = selmon->clients; c; c = c->next) -+ if (ISVISIBLE(c) && c->bw == 0) -+ resize(c, c->x, c->y, c->w - 2*borderpx, c->h - 2*borderpx, borderpx, 0); - } - - void -@@ -566,7 +573,7 @@ configurenotify(XEvent *e) - 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); -+ resizeclient(c, m->mx, m->my, m->mw, m->mh, 0); - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); - } - focus(NULL); -@@ -1112,7 +1119,7 @@ monocle(Monitor *m) - 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); -+ resize(c, m->wx, m->wy, m->ww, m->wh, 0, 0); - } - - void -@@ -1180,7 +1187,7 @@ movemouse(const Arg *arg) - && (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); -+ resize(c, nx, ny, c->w, c->h, c->bw, 1); - break; - } - } while (ev.type != ButtonRelease); -@@ -1266,14 +1273,14 @@ recttomon(int x, int y, int w, int h) - } - - void --resize(Client *c, int x, int y, int w, int h, int interact) -+resize(Client *c, int x, int y, int w, int h, int bw, int interact) - { -- if (applysizehints(c, &x, &y, &w, &h, interact)) -- resizeclient(c, x, y, w, h); -+ if (applysizehints(c, &x, &y, &w, &h, &bw, interact)) -+ resizeclient(c, x, y, w, h, bw); - } - - void --resizeclient(Client *c, int x, int y, int w, int h) -+resizeclient(Client *c, int x, int y, int w, int h, int bw) - { - XWindowChanges wc; - -@@ -1281,7 +1288,7 @@ resizeclient(Client *c, int x, int y, int w, int h) - 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; -+ c->oldbw = c->bw; c->bw = wc.border_width = bw; - XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); - configure(c); - XSync(dpy, False); -@@ -1330,7 +1337,7 @@ resizemouse(const Arg *arg) - togglefloating(NULL); - } - if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) -- resize(c, c->x, c->y, nw, nh, 1); -+ resize(c, c->x, c->y, nw, nh, c->bw, 1); - break; - } - } while (ev.type != ButtonRelease); -@@ -1477,22 +1484,20 @@ setfullscreen(Client *c, int fullscreen) - 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); -+ resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh, 0); - 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); -+ c->bw = c->oldbw; -+ resizeclient(c, c->x, c->y, c->w, c->h, c->bw); - arrange(c->mon); - } - } -@@ -1619,7 +1624,7 @@ showhide(Client *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); -+ resize(c, c->x, c->y, c->w, c->h, c->bw, 0); - showhide(c->snext); - } else { - /* hide clients bottom up */ -@@ -1673,13 +1678,17 @@ tagmon(const Arg *arg) - void - tile(Monitor *m) - { -- unsigned int i, n, h, mw, my, ty; -+ unsigned int i, n, h, mw, my, ty, bw; - Client *c; - - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - if (n == 0) - return; - -+ if (n == 1) -+ bw = 0; -+ else -+ bw = borderpx; - if (n > m->nmaster) - mw = m->nmaster ? m->ww * m->mfact : 0; - else -@@ -1687,11 +1696,11 @@ tile(Monitor *m) - for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if (i < m->nmaster) { - h = (m->wh - my) / (MIN(n, m->nmaster) - i); -- resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); -+ resize(c, m->wx, m->wy + my, mw - 2*bw, h - 2*bw, bw, 0); - 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); -+ resize(c, m->wx + mw, m->wy + ty, m->ww - mw - 2*bw, h - 2*bw, bw, 0); - ty += HEIGHT(c); - } - } -@@ -1715,7 +1724,9 @@ togglefloating(const Arg *arg) - 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); -+ selmon->sel->w - 2 * (borderpx - selmon->sel->bw), -+ selmon->sel->h - 2 * (borderpx - selmon->sel->bw), -+ borderpx, 0); - arrange(selmon); - } - diff --git a/dwm-6.2/patches/dwm-vanitygaps-20190508-6.2.diff b/dwm-6.2/patches/dwm-vanitygaps-20190508-6.2.diff deleted file mode 100644 index ea22e23..0000000 --- a/dwm-6.2/patches/dwm-vanitygaps-20190508-6.2.diff +++ /dev/null @@ -1,259 +0,0 @@ -From 20967685d6879bd611a856ade154df19da9ddc7b Mon Sep 17 00:00:00 2001 -From: Stein Gunnar Bakkeby -Date: Wed, 8 May 2019 08:07:14 +0200 -Subject: [PATCH] Vanity gaps - allows control of both inner and outer gaps - between windows and screen edge - ---- - config.def.h | 21 +++++++++ - dwm.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- - 2 files changed, 161 insertions(+), 10 deletions(-) - -diff --git a/config.def.h b/config.def.h -index 1c0b587..0927c2d 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -3,6 +3,11 @@ - /* appearance */ - static const unsigned int borderpx = 1; /* border pixel of windows */ - static const unsigned int snap = 32; /* snap pixel */ -+static const unsigned int gappih = 10; /* horiz inner gap between windows */ -+static const unsigned int gappiv = 10; /* vert inner gap between windows */ -+static const unsigned int gappoh = 10; /* horiz outer gap between windows and screen edge */ -+static const unsigned int gappov = 10; /* vert outer gap between windows and screen edge */ -+static const int smartgaps = 0; /* 1 means no outer gap when there is only one window */ - static const int showbar = 1; /* 0 means no bar */ - static const int topbar = 1; /* 0 means bottom bar */ - static const char *fonts[] = { "monospace:size=10" }; -@@ -70,6 +75,22 @@ static Key keys[] = { - { MODKEY, XK_d, incnmaster, {.i = -1 } }, - { MODKEY, XK_h, setmfact, {.f = -0.05} }, - { MODKEY, XK_l, setmfact, {.f = +0.05} }, -+ { MODKEY|Mod4Mask, XK_h, incrgaps, {.i = +1 } }, -+ { MODKEY|Mod4Mask, XK_l, incrgaps, {.i = -1 } }, -+ { MODKEY|Mod4Mask|ShiftMask, XK_h, incrogaps, {.i = +1 } }, -+ { MODKEY|Mod4Mask|ShiftMask, XK_l, incrogaps, {.i = -1 } }, -+ { MODKEY|Mod4Mask|ControlMask, XK_h, incrigaps, {.i = +1 } }, -+ { MODKEY|Mod4Mask|ControlMask, XK_l, incrigaps, {.i = -1 } }, -+ { MODKEY|Mod4Mask, XK_0, togglegaps, {0} }, -+ { MODKEY|Mod4Mask|ShiftMask, XK_0, defaultgaps, {0} }, -+ { MODKEY, XK_y, incrihgaps, {.i = +1 } }, -+ { MODKEY, XK_o, incrihgaps, {.i = -1 } }, -+ { MODKEY|ControlMask, XK_y, incrivgaps, {.i = +1 } }, -+ { MODKEY|ControlMask, XK_o, incrivgaps, {.i = -1 } }, -+ { MODKEY|Mod4Mask, XK_y, incrohgaps, {.i = +1 } }, -+ { MODKEY|Mod4Mask, XK_o, incrohgaps, {.i = -1 } }, -+ { MODKEY|ShiftMask, XK_y, incrovgaps, {.i = +1 } }, -+ { MODKEY|ShiftMask, XK_o, incrovgaps, {.i = -1 } }, - { MODKEY, XK_Return, zoom, {0} }, - { MODKEY, XK_Tab, view, {0} }, - { MODKEY|ShiftMask, XK_c, killclient, {0} }, -diff --git a/dwm.c b/dwm.c -index 4465af1..88f3e04 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -119,6 +119,10 @@ struct Monitor { - int by; /* bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ -+ int gappih; /* horizontal gap between windows */ -+ int gappiv; /* vertical gap between windows */ -+ int gappoh; /* horizontal outer gaps */ -+ int gappov; /* vertical outer gaps */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; -@@ -199,6 +203,16 @@ 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 setgaps(int oh, int ov, int ih, int iv); -+static void incrgaps(const Arg *arg); -+static void incrigaps(const Arg *arg); -+static void incrogaps(const Arg *arg); -+static void incrohgaps(const Arg *arg); -+static void incrovgaps(const Arg *arg); -+static void incrihgaps(const Arg *arg); -+static void incrivgaps(const Arg *arg); -+static void togglegaps(const Arg *arg); -+static void defaultgaps(const Arg *arg); - static void setlayout(const Arg *arg); - static void setmfact(const Arg *arg); - static void setup(void); -@@ -240,6 +254,7 @@ static char stext[256]; - static int screen; - static int sw, sh; /* X display screen geometry width, height */ - static int bh, blw = 0; /* bar geometry */ -+static int enablegaps = 1; /* enables gaps, used by togglegaps */ - static int lrpad; /* sum of left and right padding for text */ - static int (*xerrorxlib)(Display *, XErrorEvent *); - static unsigned int numlockmask = 0; -@@ -638,6 +653,10 @@ createmon(void) - m->nmaster = nmaster; - m->showbar = showbar; - m->topbar = topbar; -+ m->gappih = gappih; -+ m->gappiv = gappiv; -+ m->gappoh = gappoh; -+ m->gappov = gappov; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -@@ -1498,6 +1517,111 @@ setfullscreen(Client *c, int fullscreen) - } - - void -+setgaps(int oh, int ov, int ih, int iv) -+{ -+ if (oh < 0) oh = 0; -+ if (ov < 0) ov = 0; -+ if (ih < 0) ih = 0; -+ if (iv < 0) iv = 0; -+ -+ selmon->gappoh = oh; -+ selmon->gappov = ov; -+ selmon->gappih = ih; -+ selmon->gappiv = iv; -+ arrange(selmon); -+} -+ -+void -+togglegaps(const Arg *arg) -+{ -+ enablegaps = !enablegaps; -+ arrange(selmon); -+} -+ -+void -+defaultgaps(const Arg *arg) -+{ -+ setgaps(gappoh, gappov, gappih, gappiv); -+} -+ -+void -+incrgaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh + arg->i, -+ selmon->gappov + arg->i, -+ selmon->gappih + arg->i, -+ selmon->gappiv + arg->i -+ ); -+} -+ -+void -+incrigaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh, -+ selmon->gappov, -+ selmon->gappih + arg->i, -+ selmon->gappiv + arg->i -+ ); -+} -+ -+void -+incrogaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh + arg->i, -+ selmon->gappov + arg->i, -+ selmon->gappih, -+ selmon->gappiv -+ ); -+} -+ -+void -+incrohgaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh + arg->i, -+ selmon->gappov, -+ selmon->gappih, -+ selmon->gappiv -+ ); -+} -+ -+void -+incrovgaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh, -+ selmon->gappov + arg->i, -+ selmon->gappih, -+ selmon->gappiv -+ ); -+} -+ -+void -+incrihgaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh, -+ selmon->gappov, -+ selmon->gappih + arg->i, -+ selmon->gappiv -+ ); -+} -+ -+void -+incrivgaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh, -+ selmon->gappov, -+ selmon->gappih, -+ selmon->gappiv + arg->i -+ ); -+} -+ -+void - setlayout(const Arg *arg) - { - if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) -@@ -1673,26 +1797,32 @@ tagmon(const Arg *arg) - void - tile(Monitor *m) - { -- unsigned int i, n, h, mw, my, ty; -+ unsigned int i, n, h, r, oe = enablegaps, ie = enablegaps, mw, my, ty; - Client *c; - - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - if (n == 0) - return; - -+ if (smartgaps == n) { -+ oe = 0; // outer gaps disabled -+ } -+ - if (n > m->nmaster) -- mw = m->nmaster ? m->ww * m->mfact : 0; -+ mw = m->nmaster ? (m->ww + m->gappiv*ie) * m->mfact : 0; - else -- mw = m->ww; -- for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) -+ mw = m->ww - 2*m->gappov*oe + m->gappiv*ie; -+ for (i = 0, my = ty = m->gappoh*oe, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if (i < m->nmaster) { -- h = (m->wh - my) / (MIN(n, m->nmaster) - i); -- resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); -- my += HEIGHT(c); -+ r = MIN(n, m->nmaster) - i; -+ h = (m->wh - my - m->gappoh*oe - m->gappih*ie * (r - 1)) / r; -+ resize(c, m->wx + m->gappov*oe, m->wy + my, mw - (2*c->bw) - m->gappiv*ie, h - (2*c->bw), 0); -+ my += HEIGHT(c) + m->gappih*ie; - } else { -- h = (m->wh - ty) / (n - i); -- resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); -- ty += HEIGHT(c); -+ r = n - i; -+ h = (m->wh - ty - m->gappoh*oe - m->gappih*ie * (r - 1)) / r; -+ resize(c, m->wx + mw + m->gappov*oe, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappov*oe, h - (2*c->bw), 0); -+ ty += HEIGHT(c) + m->gappih*ie; - } - } - --- -2.7.4 - diff --git a/dwm-6.2/patches/dwm-vanitygaps-20200610-f09418b.diff b/dwm-6.2/patches/dwm-vanitygaps-20200610-f09418b.diff deleted file mode 100644 index c8b13b2..0000000 --- a/dwm-6.2/patches/dwm-vanitygaps-20200610-f09418b.diff +++ /dev/null @@ -1,262 +0,0 @@ -From c35fd03ec002e1f4476a75203ff9b5cbcc630177 Mon Sep 17 00:00:00 2001 -From: Michel Boaventura -Date: Wed, 10 Jun 2020 10:46:51 -0300 -Subject: [PATCH] Update Vanity Gaps to master - ---- - config.def.h | 21 +++++++ - dwm.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++---- - 2 files changed, 163 insertions(+), 12 deletions(-) - -diff --git a/config.def.h b/config.def.h -index 1c0b587..0927c2d 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -3,6 +3,11 @@ - /* appearance */ - static const unsigned int borderpx = 1; /* border pixel of windows */ - static const unsigned int snap = 32; /* snap pixel */ -+static const unsigned int gappih = 10; /* horiz inner gap between windows */ -+static const unsigned int gappiv = 10; /* vert inner gap between windows */ -+static const unsigned int gappoh = 10; /* horiz outer gap between windows and screen edge */ -+static const unsigned int gappov = 10; /* vert outer gap between windows and screen edge */ -+static const int smartgaps = 0; /* 1 means no outer gap when there is only one window */ - static const int showbar = 1; /* 0 means no bar */ - static const int topbar = 1; /* 0 means bottom bar */ - static const char *fonts[] = { "monospace:size=10" }; -@@ -70,6 +75,22 @@ static Key keys[] = { - { MODKEY, XK_d, incnmaster, {.i = -1 } }, - { MODKEY, XK_h, setmfact, {.f = -0.05} }, - { MODKEY, XK_l, setmfact, {.f = +0.05} }, -+ { MODKEY|Mod4Mask, XK_h, incrgaps, {.i = +1 } }, -+ { MODKEY|Mod4Mask, XK_l, incrgaps, {.i = -1 } }, -+ { MODKEY|Mod4Mask|ShiftMask, XK_h, incrogaps, {.i = +1 } }, -+ { MODKEY|Mod4Mask|ShiftMask, XK_l, incrogaps, {.i = -1 } }, -+ { MODKEY|Mod4Mask|ControlMask, XK_h, incrigaps, {.i = +1 } }, -+ { MODKEY|Mod4Mask|ControlMask, XK_l, incrigaps, {.i = -1 } }, -+ { MODKEY|Mod4Mask, XK_0, togglegaps, {0} }, -+ { MODKEY|Mod4Mask|ShiftMask, XK_0, defaultgaps, {0} }, -+ { MODKEY, XK_y, incrihgaps, {.i = +1 } }, -+ { MODKEY, XK_o, incrihgaps, {.i = -1 } }, -+ { MODKEY|ControlMask, XK_y, incrivgaps, {.i = +1 } }, -+ { MODKEY|ControlMask, XK_o, incrivgaps, {.i = -1 } }, -+ { MODKEY|Mod4Mask, XK_y, incrohgaps, {.i = +1 } }, -+ { MODKEY|Mod4Mask, XK_o, incrohgaps, {.i = -1 } }, -+ { MODKEY|ShiftMask, XK_y, incrovgaps, {.i = +1 } }, -+ { MODKEY|ShiftMask, XK_o, incrovgaps, {.i = -1 } }, - { MODKEY, XK_Return, zoom, {0} }, - { MODKEY, XK_Tab, view, {0} }, - { MODKEY|ShiftMask, XK_c, killclient, {0} }, -diff --git a/dwm.c b/dwm.c -index 9fd0286..50dbbaf 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -119,6 +119,10 @@ struct Monitor { - int by; /* bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ -+ int gappih; /* horizontal gap between windows */ -+ int gappiv; /* vertical gap between windows */ -+ int gappoh; /* horizontal outer gaps */ -+ int gappov; /* vertical outer gaps */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; -@@ -200,6 +204,16 @@ 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 setgaps(int oh, int ov, int ih, int iv); -+static void incrgaps(const Arg *arg); -+static void incrigaps(const Arg *arg); -+static void incrogaps(const Arg *arg); -+static void incrohgaps(const Arg *arg); -+static void incrovgaps(const Arg *arg); -+static void incrihgaps(const Arg *arg); -+static void incrivgaps(const Arg *arg); -+static void togglegaps(const Arg *arg); -+static void defaultgaps(const Arg *arg); - static void setlayout(const Arg *arg); - static void setmfact(const Arg *arg); - static void setup(void); -@@ -241,6 +255,7 @@ static char stext[256]; - static int screen; - static int sw, sh; /* X display screen geometry width, height */ - static int bh, blw = 0; /* bar geometry */ -+static int enablegaps = 1; /* enables gaps, used by togglegaps */ - static int lrpad; /* sum of left and right padding for text */ - static int (*xerrorxlib)(Display *, XErrorEvent *); - static unsigned int numlockmask = 0; -@@ -639,6 +654,10 @@ createmon(void) - m->nmaster = nmaster; - m->showbar = showbar; - m->topbar = topbar; -+ m->gappih = gappih; -+ m->gappiv = gappiv; -+ m->gappoh = gappoh; -+ m->gappov = gappov; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -@@ -1498,6 +1517,111 @@ setfullscreen(Client *c, int fullscreen) - } - } - -+void -+setgaps(int oh, int ov, int ih, int iv) -+{ -+ if (oh < 0) oh = 0; -+ if (ov < 0) ov = 0; -+ if (ih < 0) ih = 0; -+ if (iv < 0) iv = 0; -+ -+ selmon->gappoh = oh; -+ selmon->gappov = ov; -+ selmon->gappih = ih; -+ selmon->gappiv = iv; -+ arrange(selmon); -+} -+ -+void -+togglegaps(const Arg *arg) -+{ -+ enablegaps = !enablegaps; -+ arrange(selmon); -+} -+ -+void -+defaultgaps(const Arg *arg) -+{ -+ setgaps(gappoh, gappov, gappih, gappiv); -+} -+ -+void -+incrgaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh + arg->i, -+ selmon->gappov + arg->i, -+ selmon->gappih + arg->i, -+ selmon->gappiv + arg->i -+ ); -+} -+ -+void -+incrigaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh, -+ selmon->gappov, -+ selmon->gappih + arg->i, -+ selmon->gappiv + arg->i -+ ); -+} -+ -+void -+incrogaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh + arg->i, -+ selmon->gappov + arg->i, -+ selmon->gappih, -+ selmon->gappiv -+ ); -+} -+ -+void -+incrohgaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh + arg->i, -+ selmon->gappov, -+ selmon->gappih, -+ selmon->gappiv -+ ); -+} -+ -+void -+incrovgaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh, -+ selmon->gappov + arg->i, -+ selmon->gappih, -+ selmon->gappiv -+ ); -+} -+ -+void -+incrihgaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh, -+ selmon->gappov, -+ selmon->gappih + arg->i, -+ selmon->gappiv -+ ); -+} -+ -+void -+incrivgaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh, -+ selmon->gappov, -+ selmon->gappih, -+ selmon->gappiv + arg->i -+ ); -+} -+ - void - setlayout(const Arg *arg) - { -@@ -1674,28 +1798,34 @@ tagmon(const Arg *arg) - void - tile(Monitor *m) - { -- unsigned int i, n, h, mw, my, ty; -+ unsigned int i, n, h, r, oe = enablegaps, ie = enablegaps, mw, my, ty; - Client *c; - - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - if (n == 0) - return; - -+ if (smartgaps == n) { -+ oe = 0; // outer gaps disabled -+ } -+ - if (n > m->nmaster) -- mw = m->nmaster ? m->ww * m->mfact : 0; -+ mw = m->nmaster ? (m->ww + m->gappiv*ie) * m->mfact : 0; - else -- mw = m->ww; -- for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) -+ mw = m->ww - 2*m->gappov*oe + m->gappiv*ie; -+ for (i = 0, my = ty = m->gappoh*oe, 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); -+ r = MIN(n, m->nmaster) - i; -+ h = (m->wh - my - m->gappoh*oe - m->gappih*ie * (r - 1)) / r; -+ resize(c, m->wx + m->gappov*oe, m->wy + my, mw - (2*c->bw) - m->gappiv*ie, h - (2*c->bw), 0); -+ if (my + HEIGHT(c) + m->gappih*ie < m->wh) -+ my += HEIGHT(c) + m->gappih*ie; - } 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); -+ r = n - i; -+ h = (m->wh - ty - m->gappoh*oe - m->gappih*ie * (r - 1)) / r; -+ resize(c, m->wx + mw + m->gappov*oe, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappov*oe, h - (2*c->bw), 0); -+ if (ty + HEIGHT(c) + m->gappih*ie < m->wh) -+ ty += HEIGHT(c) + m->gappih*ie; - } - } - --- -2.27.0 - diff --git a/dwm-6.2/patches/patches.txt b/dwm-6.2/patches/patches.txt deleted file mode 100644 index d365999..0000000 --- a/dwm-6.2/patches/patches.txt +++ /dev/null @@ -1,8 +0,0 @@ -https://dwm.suckless.org/patches/alternativetags/ -https://dwm.suckless.org/patches/bottomstack/ -https://dwm.suckless.org/patches/centeredwindowname/ -https://dwm.suckless.org/patches/cfacts/ -https://dwm.suckless.org/patches/colorbar/ -https://dwm.suckless.org/patches/cropwindows/ -https://dwm.suckless.org/status_monitor/ - diff --git a/dwm-6.2/patches/wm-colorbar-6.2.diff b/dwm-6.2/patches/wm-colorbar-6.2.diff deleted file mode 100644 index 91c067d..0000000 --- a/dwm-6.2/patches/wm-colorbar-6.2.diff +++ /dev/null @@ -1,68 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 1c0b587..a516645 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -16,6 +16,11 @@ static const char *colors[][3] = { - /* fg bg border */ - [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, - [SchemeSel] = { col_gray4, col_cyan, col_cyan }, -+ [SchemeStatus] = { col_gray3, col_gray1, "#000000" }, // Statusbar right {text,background,not used but cannot be empty} -+ [SchemeTagsSel] = { col_gray4, col_cyan, "#000000" }, // Tagbar left selected {text,background,not used but cannot be empty} -+ [SchemeTagsNorm] = { col_gray3, col_gray1, "#000000" }, // Tagbar left unselected {text,background,not used but cannot be empty} -+ [SchemeInfoSel] = { col_gray4, col_cyan, "#000000" }, // infobar middle selected {text,background,not used but cannot be empty} -+ [SchemeInfoNorm] = { col_gray3, col_gray1, "#000000" }, // infobar middle unselected {text,background,not used but cannot be empty} - }; - - /* tagging */ -diff --git a/dwm.c b/dwm.c -index 4465af1..0d1d2f7 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -59,7 +59,7 @@ - - /* enums */ - enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ --enum { SchemeNorm, SchemeSel }; /* color schemes */ -+enum { SchemeNorm, SchemeSel, SchemeStatus, SchemeTagsSel, SchemeTagsNorm, SchemeInfoSel, SchemeInfoNorm }; /* color schemes */ - enum { NetSupported, NetWMName, NetWMState, NetWMCheck, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ -@@ -703,7 +703,7 @@ drawbar(Monitor *m) - - /* 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]); -+ drw_setscheme(drw, scheme[SchemeStatus]); - sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ - drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0); - } -@@ -716,7 +716,7 @@ drawbar(Monitor *m) - 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_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeTagsSel : SchemeTagsNorm]); - 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, -@@ -725,17 +725,17 @@ drawbar(Monitor *m) - x += w; - } - w = blw = TEXTW(m->ltsymbol); -- drw_setscheme(drw, scheme[SchemeNorm]); -+ drw_setscheme(drw, scheme[SchemeTagsNorm]); - x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); - - if ((w = m->ww - sw - x) > bh) { - if (m->sel) { -- drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); -+ drw_setscheme(drw, scheme[m == selmon ? SchemeInfoSel : SchemeInfoNorm]); - 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_setscheme(drw, scheme[SchemeInfoNorm]); - drw_rect(drw, x, 0, w, bh, 1, 1); - } - } diff --git a/dwm-6.2/transient.c b/dwm-6.2/transient.c deleted file mode 100644 index 040adb5..0000000 --- a/dwm-6.2/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/dwm-6.2/util.c b/dwm-6.2/util.c deleted file mode 100644 index fe044fc..0000000 --- a/dwm-6.2/util.c +++ /dev/null @@ -1,35 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include -#include -#include -#include - -#include "util.h" - -void * -ecalloc(size_t nmemb, size_t size) -{ - void *p; - - if (!(p = calloc(nmemb, size))) - die("calloc:"); - return p; -} - -void -die(const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - - if (fmt[0] && fmt[strlen(fmt)-1] == ':') { - fputc(' ', stderr); - perror(NULL); - } else { - fputc('\n', stderr); - } - - exit(1); -} diff --git a/dwm-6.2/util.h b/dwm-6.2/util.h deleted file mode 100644 index f633b51..0000000 --- a/dwm-6.2/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/home/gtk/.config/gtk-2.0/gtkfilechooser.ini b/home/gtk/.config/gtk-2.0/gtkfilechooser.ini index 8996686..1da176b 100644 --- a/home/gtk/.config/gtk-2.0/gtkfilechooser.ini +++ b/home/gtk/.config/gtk-2.0/gtkfilechooser.ini @@ -2,10 +2,10 @@ LocationMode=path-bar ShowHidden=false ShowSizeColumn=true -GeometryX=492 -GeometryY=235 -GeometryWidth=936 -GeometryHeight=637 +GeometryX=0 +GeometryY=0 +GeometryWidth=637 +GeometryHeight=520 SortColumn=name SortOrder=ascending StartupMode=recent diff --git a/home/picom/.config/picom/picom.conf. b/home/picom/.config/picom/picom.conf. new file mode 100644 index 0000000..07e05b2 --- /dev/null +++ b/home/picom/.config/picom/picom.conf. @@ -0,0 +1,34 @@ +inactive-dim = 0.5; +active-opacity = 1.0; +detect-client-opacity = true; +detect-rounded-corners = true; +blur: +{ + method = "kawase"; + strength = 8; + background = false; + background-frame = false; + background-fixed = false; +}; + blur-background-exclude = [ + "class_g = 'keynav'" + ]; + corner-radius = 0; + rounded-corners-exclude = [ + "window_type = 'dock'", + "_NET_WM_STATE@:32a *= '_NET_WM_STATE_FULLSCREEN'", + "class_g = 'keynav'", + ]; + round-borders = 0; + round-borders-exclude = [ + "class_g = 'keynav'" + ]; + +opacity-rule = [ + "80:class_g = 'Zathura'", + "80:class_g = 'TelegramDesktop'", + "80:class_g = 'Discord'", + "80:class_g = 'Emacs'", + "100:class_g = 'keynav'", + "85:class_g = 'Alacritty'" + ]; diff --git a/home/picom/.config/picom/picom.conf_ b/home/picom/.config/picom/picom.conf_ deleted file mode 100644 index 2d06630..0000000 --- a/home/picom/.config/picom/picom.conf_ +++ /dev/null @@ -1,414 +0,0 @@ - -corner-radius = 10; -rounded-corners-exclude = [ -# "class_g = 'awesome'", -# "class_g = 'Polybar'", - "class_g *= 'dwm'", -]; -rounded-corners-rule = [ - "5:class_g = 'Dunst'", - -]; -round-borders = 10; -round-borders-exclude = []; - -round-borders-rule = [ - "3:class_g = 'XTerm'", - "3:class_g = 'URxvt'", - "10:class_g = 'Alacritty'", - "5:class_g = 'Dunst'", - "15:class_g = 'Signal'" -]; - - - - - - - - - - - - - -shadow = true; - - - -shadow-radius = 20; - -shadow-opacity = 0.75 - - - -shadow-offset-x = -10; - - - -shadow-offset-y = -10; -shadow-exclude = [ - - "name = 'Polybar'", - "class_g *= 'border'", - "name = 'xmobar'", - "class_g = 'Conky'", - "class_g *= 'dwm'", - "class_g = 'Polybar'", - "class_g ?= 'Notify-osd'", - "class_g = 'Cairo-clock'", - "_GTK_FRAME_EXTENTS@:c" -]; - - - - - - - - - - - - - - - - - - - - -fading = true - - - -fade-in-step = 0.03; - - - -fade-out-step = 0.03; - - - - - - - - - - - - - - - - - - - - - -inactive-opacity = 1; - - - -frame-opacity = 1; - - - - - - -inactive-opacity-override = false; - - - - - -inactive-dim = 0 - - - -focus-exclude = [ "class_g = 'Cairo-clock'" ]; - - - - - - - - - - - -opacity-rule = [ - "95:class_g = 'Emacs'", - "95:class_g *= 'Alacritty'", - "78:class_g *= 'Zathura'", - "80:class_g = 'dropdown'", - "50:class_g = 'Firefox'", - "90:class_g *= 'emacs'", - "90:class_g = 'dmenu'", - "95:name *= 'alacritty'", - "90:name = 'emacs'", - "85:name *= 'xmobar'", - "95:class_g = 'Spotify'", - "95:class_g = 'Polybar'" - ] - - -blur: -{ - method = "kawase"; - size = 10; - deviation = 2.0; -}; - - -blur-kern = "3x3box"; - -blur-background-exclude = [ - - "window_type = 'desktop'", - "_GTK_FRAME_EXTENTS@:c" -]; - - -backend = "glx"; -vsync = true - -mark-wmwin-focused = true; - -mark-ovredir-focused = true; - - - - -detect-rounded-corners = true - - - - - - -detect-client-opacity = true; - - - - - -refresh-rate = 0 - - - - - - - - - - - - - - - - - - - -unredir-if-possible = false - - - - - - - - - - - -detect-transient = true - - - - - - -detect-client-leader = true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -use-damage = true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -log-level = "warn"; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -wintypes: -{ - tooltip = { - - fade = false; - - shadow = true; - - opacity = 1; - - focus = true; - }; - - dock = { - full-shadow = true; - opacity = 1; - } - - dnd = { - shadow = false; - } - - popup_menu = { - full-shaodw = false; - opacity = 1; - } - - dropdown_menu = { - full-shaodw = false; - opacity = 1; - } - - notification = { - - fade = true; - - shadow = true; - - opacity = 1; - - focus = true; - }; -}; - - diff --git a/home/picom/.config/picom/picom.conf b/home/picom/.config/picom/picom.conff similarity index 74% rename from home/picom/.config/picom/picom.conf rename to home/picom/.config/picom/picom.conff index fa9387b..cf770a7 100644 --- a/home/picom/.config/picom/picom.conf +++ b/home/picom/.config/picom/picom.conff @@ -5,6 +5,7 @@ rounded-corners-exclude = [ "class_g *= 'dwm'", "class_g = 'Xmobar'", "class_g = 'xmobar'", + "class_g = 'firefox'", "name = 'xmobar'", "name *= 'emacs'", "class_g = 'emacs'" @@ -15,6 +16,7 @@ rounded-corners-rule = [ "0:class_g = 'awesome'", "0:name = 'xmobar'", + "0:name = 'firefox'", "0:class_g = 'Xmobar'", "0:name = 'Xmobar'", "0:class_g = 'xmonad'", @@ -22,12 +24,8 @@ rounded-corners-rule = [ "5:class_g = 'Deadd-notification-center'", "5:class_g = 'emacs'", "50:name = 'video0'", - "50:class_g = 'firefox'" ]; -corner-radius-rule = [ - "50:class_g = 'firefox'" -] corner-radius = 5; round-borders = 5; round-borders-exclude = [ @@ -40,6 +38,7 @@ round-borders-rule = [ "3:class_g = 'Alacritty'", "3:class_g = 'eww'", "0:name = 'xmobar'", + "0:name = 'firefox'", "0:class_g = 'Xmobar'", "0:class_g = 'xmonad'", "5:class_g = 'Dunst'", @@ -47,9 +46,9 @@ round-borders-rule = [ "5:class_g = 'Signal'", "5:class_g = 'Deadd-notification-center'", ]; -shadow = false; +shadow = true; shadow-radius = 5; -shadow-opacity = 0.4 +shadow-opacity = 0.4; shadow-offset-x = -1; shadow-offset-y = -1; shadow-exclude = [ @@ -68,45 +67,45 @@ shadow-exclude = [ ]; -fading = false +fading = true; fade-out-step = 0.03; inactive-opacity = 1; frame-opacity = 1; inactive-opacity-override = false; -inactive-dim = 0 +inactive-dim = 0; focus-exclude = [ "class_g = 'Cairo-clock'" ]; -opacity-rule = [ -"00:name *= 'blur_full'", -"80:name = 'emacs@dropdown'", -"75:class_g *= 'Spotify'", -"85:class_g *= 'Anki'", - - "85:class_g *= 'Go-for-it'", - "95:class_g *= 'notion'", - "95:class_g = 'Emacs'", - "90:class_g *= 'Alacritty'", - "78:class_g *= 'Zathura'", - "80:class_g = 'dropdown'", - "50:class_g = 'Firefox'", - "90:class_g *= 'emacs'", - "90:class_g = 'dmenu'", - "90:class_g = 'Evolution'", - "98:name *= 'alacritty'", - "90:name = 'emacs'", - "95:class_g = 'Polybar'", - "85:name *= 'scratchpad'", - "85:class_g= 'Dunst'", - "85:name *= 'Rust Programming Language'", - "95:class_g = 'Deadd-notification-center'", - "85:class_g *= 'ticktick'" - ] + opacity-rule = [ + "00:name *= 'blur_full'", +# "80:name = 'emacs@dropdown'", +# "75:class_g *= 'Spotify'", +# "85:class_g *= 'Anki'", +# +# "85:class_g *= 'Go-for-it'", +# "95:class_g *= 'notion'", +# "95:class_g = 'Emacs'", + "90:class_g *= 'Alacritty'", +# "78:class_g *= 'Zathura'", +# "80:class_g = 'dropdown'", +# "50:class_g = 'Firefox'", +# "90:class_g *= 'emacs'", +# "90:class_g = 'dmenu'", +# "90:class_g = 'Evolution'", +# "98:name *= 'alacritty'", +# "90:name = 'emacs'", +# "95:class_g = 'Polybar'", +# "85:name *= 'scratchpad'", +# "85:class_g= 'Dunst'", +# "85:name *= 'Rust Programming Language'", +# "95:class_g = 'Deadd-notification-center'", +# "85:class_g *= 'ticktick'" + ] blur: { method = "kawase"; - size = 50; + size = 30; deviation = 9.0; }; @@ -121,6 +120,7 @@ blur-background-exclude = [ backend = "glx"; +glx-no-stencli = true; vsync = true mark-wmwin-focused = true; diff --git a/home/pure_emacs/.emacs.d/config.org b/home/pure_emacs/.emacs.d/config.org index 578f37d..7c0b2ca 100644 --- a/home/pure_emacs/.emacs.d/config.org +++ b/home/pure_emacs/.emacs.d/config.org @@ -17,6 +17,7 @@ * Packages #+begin_src emacs-lisp +(require 'package) (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/")) @@ -35,6 +36,9 @@ #+end_src + +#+RESULTS: + * UI ** Cleaning up #+begin_src emacs-lisp @@ -49,24 +53,39 @@ (global-visual-line-mode 1) (global-visual-line-mode) #+end_src + + #+RESULTS: + : t + ** Theme #+begin_src emacs-lisp - (require 'use-package) - (use-package doom-themes) - (setq use-package-always-ensure t) - (custom-set-variables - ;; custom-set-variables was added by Custom. - ;; If you edit it by hand, you could mess it up, so be careful. - ;; Your init file should contain only one such instance. - ;; If there is more than one, they won't work right. -; '(custom-safe-themes -; '("6b5c518d1c250a8ce17463b7e435e9e20faa84f3f7defba8b579d4f5925f60c1" "75b8719c741c6d7afa290e0bb394d809f0cc62045b93e1d66cd646907f8e6d43" "7661b762556018a44a29477b84757994d8386d6edee909409fabe0631952dad9" default)) - '(package-selected-packages - '(org-roam-server visual-fill-column org-bullets workgroups2 neotree treemacs-persp treemacs-magit treemacs-icons-dired treemacs-projectile treemacs-evil treemacs-all-the-icons ivy-rich which-key rainbow-delimiters highlight-parentheses org-roam general use-package))) + (require 'use-package) + (use-package doom-themes) + '(custom-enabled-themes '(gruvbox)) + '(custom-safe-themes + '("d14f3df28603e9517eb8fb7518b662d653b25b26e83bd8e129acea042b774298" "6b5c518d1c250a8ce17463b7e435e9e20faa84f3f7defba8b579d4f5925f60c1" default)) - (load-theme 'doom-gruvbox) + (use-package gruvbox-theme + :ensure t + :config + (load-theme 'gruvbox-dark-hard) + ) + (setq use-package-always-ensure t) + (custom-set-variables + ;; custom-set-variables was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + ; '(custom-safe-themes + ; '("6b5c518d1c250a8ce17463b7e435e9e20faa84f3f7defba8b579d4f5925f60c1" "75b8719c741c6d7afa290e0bb394d809f0cc62045b93e1d66cd646907f8e6d43" "7661b762556018a44a29477b84757994d8386d6edee909409fabe0631952dad9" default)) + '(package-selected-packages + '(org-roam-server visual-fill-column org-bullets workgroups2 neotree treemacs-persp treemacs-magit treemacs-icons-dired treemacs-projectile treemacs-evil treemacs-all-the-icons ivy-rich which-key rainbow-delimiters highlight-parentheses org-roam general use-package))) + #+end_src + +#+RESULTS: + ** Modeline #+begin_src emacs-lisp (use-package doom-modeline @@ -78,6 +97,10 @@ #+end_src + +#+RESULTS: +: t + ** Fonts #+begin_src emacs-lisp @@ -87,13 +110,16 @@ ;;(set-fontset-font "fontset-startup" 'unicode ;; (font-spec :name "Mononoki Nerd Font" :size 14)) -(when (member "Noto Color Emoji" (font-family-list)) - (set-fontset-font t 'unicode "Noto Color Emoji" nil 'prepend)) +(when (member "Twitter Color Emoji" (font-family-list)) + (set-fontset-font t 'unicode "Twitter Color Emoji" nil 'prepend)) ;; ☺️ ☻ 😃 😄 😅 😆 😊 😎 😇 😈 😏 🤣 🤩 🤪 🥳 😁 😀 😂 🤠 🤡 🤑 🤓 🤖 😗 😚 😘 😙 😉 🤗 😍 🥰 🤤 😋 🤔 🤨 🧐 🤭 🤫 😯 🤐 😌 😖 😕 😳 😔 🤥 🥴 😮 😲 🤯 😩 😫 🥱 😪 😴 😵 ☹️ 😦 😞 😥 😟 😢 😭 🤢 🤮 😷 🤒 🤕 🥵 🥶 🥺 😬 😓 😰 😨 😱 😒 😠 😡 😤 😣 😧 🤬 😸 😹 😺 😻 😼 😽 😾 😿 🙀 🙈 🙉 🙊 🤦 🤷 🙅 🙆 🙋 🙌 🙍 🙎 🙇 🙏 👯 💃 🕺 🤳 💇 💈 💆 🧖 🧘 🧍 🧎 👰 🤰 🤱 👶 🧒 👦 👧 👩 👨 🧑 🧔 🧓 👴 👵 👤 👥 👪 👫 👬 👭 👱 👳 👲 🧕 👸 🤴 🎅 🤶 🧏 🦻 🦮 🦯 🦺 🦼 🦽 🦾 🦿 🤵 👮 👷 💁 💂 🕴 🕵️ 🦸 🦹 🧙 🧚 🧜 🧝 🧞 🧛 🧟 👼 👿 👻 👹 👺 👽 👾 🛸 💀 ☠️ 🕱 🧠 🦴 👁 👀 👂 👃 👄 🗢 👅 🦷 🦵 🦶 💭 🗬 🗭 💬 🗨 🗩 💦 💧 💢 💫 💤 💨 💥 💪 🗲 🔥 💡 💩 💯 ;; Fallback for emojies #+end_src + +#+RESULTS: + ** Line Numbers #+begin_src emacs-lisp (dolist (mode '(text-mode-hook @@ -110,6 +136,8 @@ #+end_src +#+RESULTS: + ** Brakets #+begin_src emacs-lisp (use-package highlight-parentheses @@ -121,6 +149,10 @@ :hook (prog-mode . rainbow-delimiters-mode)) #+end_src + +#+RESULTS: +| rainbow-delimiters-mode | (lambda nil (display-line-numbers-mode 1) (setq display-line-numbers 'relative)) | + ** Treemacs #+begin_src emacs-lisp (use-package all-the-icons) @@ -236,6 +268,9 @@ #+end_src + +#+RESULTS: + *** Theme #+begin_src emacs-lisp (treemacs-create-theme "Material" @@ -255,9 +290,13 @@ (treemacs-create-icon :file "editorconfig.png" :fallback "📖" :extensions ("editorconfig")) (treemacs-create-icon :file "org.png" :fallback "🐴" :extensions ("org")) (treemacs-create-icon :file "rust.png" :fallback "🐴" :extensions ("rs")) + (treemacs-create-icon :file "dart.png" :fallback "🐴" :extensions ("dart")) + (treemacs-create-icon :file "dart.png" :fallback "🐴" :extensions ("dt")) (treemacs-create-icon :file "haskell.png" :fallback "🐴" :extensions ("hs" "haskell")) (treemacs-create-icon :file "c.png" :fallback "🐴" :extensions ("c")) (treemacs-create-icon :file "cpp.png" :fallback "🐴" :extensions ("cpp" "c++")) + (treemacs-create-icon :file "nix.png" :fallback "🐴" :extensions ("nix")) + (treemacs-create-icon :file "lock.png" :fallback "🐴" :extensions ("lock" "lck")) (treemacs-create-icon :file "h.png" :fallback "🐴" :extensions ("h")) (treemacs-create-icon :file "diff.png" :fallback "🐴" :extensions ("diff")) (treemacs-create-icon :file "makefile.png" :fallback "🐴" :extensions ("mk" "make" "Makefile")) @@ -273,7 +312,7 @@ (treemacs-create-icon :file "image.png" :fallback "🗃️" :extensions ("png" "jpg")) (treemacs-create-icon :file "svg.png" :fallback "🗃️" :extensions ("svg")) (treemacs-create-icon :file "css.png" :fallback "🗃️" :extensions ("css")) - (treemacs-create-icon :file "console.png" :fallback "🗃️" :extensions ("bash" "sh")) + (treemacs-create-icon :file "console.png" :fallback "🗃️" :extensions ("bash" "sh" "install" "setup")) (treemacs-create-icon :file "certificate.png" :fallback "🗃️" :extensions ("cert" "LICENSE" "license" "gpl" "mit" "gpl3" "gplv3" "apache")) (treemacs-create-icon :file "database.png" :fallback "🗃️" :extensions ("sqlite" "db" "sql")) (treemacs-create-icon :file "lua.png" :fallback "🗃️" :extensions ("lua")) @@ -299,6 +338,9 @@ (treemacs-load-theme 'Material) #+end_src + +#+RESULTS: + * Evil Mode #+begin_src emacs-lisp (use-package undo-tree) @@ -332,6 +374,10 @@ #+end_src + +#+RESULTS: +: t + * Keybindings #+begin_src emacs-lisp @@ -403,6 +449,9 @@ #+end_src + +#+RESULTS: + * Suggestions #+begin_src emacs-lisp (use-package which-key @@ -417,6 +466,9 @@ #+end_src + +#+RESULTS: + * Org ** Fonts #+begin_src emacs-lisp @@ -455,6 +507,10 @@ #+end_src + +#+RESULTS: +: t + ** Org mode #+begin_src emacs-lisp @@ -572,6 +628,10 @@ #+end_src + +#+RESULTS: +| org-tempo-setup | my/visual-fill | org-bullets-mode | variable-pitch-mode | my/org-mode-setup | #[0 \300\301\302\303\304$\207 [add-hook change-major-mode-hook org-show-all append local] 5] | #[0 \300\301\302\303\304$\207 [add-hook change-major-mode-hook org-babel-show-result-all append local] 5] | org-babel-result-hide-spec | org-babel-hide-all-hashes | #[0 \301\211\207 [imenu-create-index-function org-imenu-get-tree] 2] | (lambda nil (display-line-numbers-mode 0)) | + #+begin_src emacs-lisp (defun my/visual-fill () (setq visual-fill-column-width 140 @@ -599,6 +659,9 @@ #+end_src +#+RESULTS: +: ((json . src json) (yaml . src yaml) (py . src python) (ts . src typescript) (sc . src scheme) (el . src emacs-lisp) (sh . src sh) (a . export ascii) (c . center) (C . comment) (e . example) (E . export) (h . export html) (l . export latex) (q . quote) (s . src) (v . verse)) + ** Org roam #+begin_src emacs-lisp (use-package org-roam-server) @@ -646,3 +709,6 @@ (require 'org-roam-protocol) #+end_src + +#+RESULTS: +: org-roam-protocol diff --git a/home/pure_emacs/.emacs.d/init.el b/home/pure_emacs/.emacs.d/init.el index bb6d97e..23342f0 100644 --- a/home/pure_emacs/.emacs.d/init.el +++ b/home/pure_emacs/.emacs.d/init.el @@ -1,3 +1,4 @@ +(require 'package) (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/")) @@ -26,21 +27,27 @@ (global-visual-line-mode) (require 'use-package) - (use-package doom-themes) - (setq use-package-always-ensure t) - -(custom-set-variables - ;; custom-set-variables was added by Custom. - ;; If you edit it by hand, you could mess it up, so be careful. - ;; Your init file should contain only one such instance. - ;; If there is more than one, they won't work right. - '(custom-safe-themes - '("75b8719c741c6d7afa290e0bb394d809f0cc62045b93e1d66cd646907f8e6d43" default)) - '(package-selected-packages - '(org-roam-server visual-fill-column org-bullets workgroups2 neotree treemacs-persp treemacs-magit treemacs-icons-dired treemacs-projectile treemacs-evil treemacs-all-the-icons ivy-rich which-key rainbow-delimiters highlight-parentheses org-roam general use-package))) + (use-package doom-themes) +'(custom-enabled-themes '(gruvbox)) +'(custom-safe-themes + '("d14f3df28603e9517eb8fb7518b662d653b25b26e83bd8e129acea042b774298" "6b5c518d1c250a8ce17463b7e435e9e20faa84f3f7defba8b579d4f5925f60c1" default)) - (load-theme 'doom-gruvbox) + (use-package gruvbox-theme + :ensure t + :config + (load-theme 'gruvbox-dark-hard) + ) + (setq use-package-always-ensure t) + (custom-set-variables + ;; custom-set-variables was added by Custom. + ;; If you edit it by hand, you could mess it up, so be careful. + ;; Your init file should contain only one such instance. + ;; If there is more than one, they won't work right. + ; '(custom-safe-themes + ; '("6b5c518d1c250a8ce17463b7e435e9e20faa84f3f7defba8b579d4f5925f60c1" "75b8719c741c6d7afa290e0bb394d809f0cc62045b93e1d66cd646907f8e6d43" "7661b762556018a44a29477b84757994d8386d6edee909409fabe0631952dad9" default)) + '(package-selected-packages + '(org-roam-server visual-fill-column org-bullets workgroups2 neotree treemacs-persp treemacs-magit treemacs-icons-dired treemacs-projectile treemacs-evil treemacs-all-the-icons ivy-rich which-key rainbow-delimiters highlight-parentheses org-roam general use-package))) (use-package doom-modeline :init @@ -55,8 +62,8 @@ ;;(set-fontset-font "fontset-startup" 'unicode ;; (font-spec :name "Mononoki Nerd Font" :size 14)) -(when (member "Noto Color Emoji" (font-family-list)) - (set-fontset-font t 'unicode "Noto Color Emoji" nil 'prepend)) +(when (member "Twitter Color Emoji" (font-family-list)) + (set-fontset-font t 'unicode "Twitter Color Emoji" nil 'prepend)) ;; ☺️ ☻ 😃 😄 😅 😆 😊 😎 😇 😈 😏 🤣 🤩 🤪 🥳 😁 😀 😂 🤠 🤡 🤑 🤓 🤖 😗 😚 😘 😙 😉 🤗 😍 🥰 🤤 😋 🤔 🤨 🧐 🤭 🤫 😯 🤐 😌 😖 😕 😳 😔 🤥 🥴 😮 😲 🤯 😩 😫 🥱 😪 😴 😵 ☹️ 😦 😞 😥 😟 😢 😭 🤢 🤮 😷 🤒 🤕 🥵 🥶 🥺 😬 😓 😰 😨 😱 😒 😠 😡 😤 😣 😧 🤬 😸 😹 😺 😻 😼 😽 😾 😿 🙀 🙈 🙉 🙊 🤦 🤷 🙅 🙆 🙋 🙌 🙍 🙎 🙇 🙏 👯 💃 🕺 🤳 💇 💈 💆 🧖 🧘 🧍 🧎 👰 🤰 🤱 👶 🧒 👦 👧 👩 👨 🧑 🧔 🧓 👴 👵 👤 👥 👪 👫 👬 👭 👱 👳 👲 🧕 👸 🤴 🎅 🤶 🧏 🦻 🦮 🦯 🦺 🦼 🦽 🦾 🦿 🤵 👮 👷 💁 💂 🕴 🕵️ 🦸 🦹 🧙 🧚 🧜 🧝 🧞 🧛 🧟 👼 👿 👻 👹 👺 👽 👾 🛸 💀 ☠️ 🕱 🧠 🦴 👁 👀 👂 👃 👄 🗢 👅 🦷 🦵 🦶 💭 🗬 🗭 💬 🗨 🗩 💦 💧 💢 💫 💤 💨 💥 💪 🗲 🔥 💡 💩 💯 ;; Fallback for emojies @@ -208,9 +215,13 @@ (treemacs-create-icon :file "editorconfig.png" :fallback "📖" :extensions ("editorconfig")) (treemacs-create-icon :file "org.png" :fallback "🐴" :extensions ("org")) (treemacs-create-icon :file "rust.png" :fallback "🐴" :extensions ("rs")) + (treemacs-create-icon :file "dart.png" :fallback "🐴" :extensions ("dart")) + (treemacs-create-icon :file "dart.png" :fallback "🐴" :extensions ("dt")) (treemacs-create-icon :file "haskell.png" :fallback "🐴" :extensions ("hs" "haskell")) (treemacs-create-icon :file "c.png" :fallback "🐴" :extensions ("c")) (treemacs-create-icon :file "cpp.png" :fallback "🐴" :extensions ("cpp" "c++")) + (treemacs-create-icon :file "nix.png" :fallback "🐴" :extensions ("nix")) + (treemacs-create-icon :file "lock.png" :fallback "🐴" :extensions ("lock" "lck")) (treemacs-create-icon :file "h.png" :fallback "🐴" :extensions ("h")) (treemacs-create-icon :file "diff.png" :fallback "🐴" :extensions ("diff")) (treemacs-create-icon :file "makefile.png" :fallback "🐴" :extensions ("mk" "make" "Makefile")) @@ -226,7 +237,7 @@ (treemacs-create-icon :file "image.png" :fallback "🗃️" :extensions ("png" "jpg")) (treemacs-create-icon :file "svg.png" :fallback "🗃️" :extensions ("svg")) (treemacs-create-icon :file "css.png" :fallback "🗃️" :extensions ("css")) - (treemacs-create-icon :file "console.png" :fallback "🗃️" :extensions ("bash" "sh")) + (treemacs-create-icon :file "console.png" :fallback "🗃️" :extensions ("bash" "sh" "install" "setup")) (treemacs-create-icon :file "certificate.png" :fallback "🗃️" :extensions ("cert" "LICENSE" "license" "gpl" "mit" "gpl3" "gplv3" "apache")) (treemacs-create-icon :file "database.png" :fallback "🗃️" :extensions ("sqlite" "db" "sql")) (treemacs-create-icon :file "lua.png" :fallback "🗃️" :extensions ("lua")) diff --git a/home/scripts/.local/scripts/status/statusbar b/home/scripts/.local/scripts/status/statusbar index aa6b577..2486364 100755 --- a/home/scripts/.local/scripts/status/statusbar +++ b/home/scripts/.local/scripts/status/statusbar @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh battery () diff --git a/home/vim/.config/nvim/.netrwhist b/home/vim/.config/nvim/.netrwhist new file mode 100644 index 0000000..b7d97e5 --- /dev/null +++ b/home/vim/.config/nvim/.netrwhist @@ -0,0 +1,4 @@ +let g:netrw_dirhistmax =10 +let g:netrw_dirhistcnt =2 +let g:netrw_dirhist_2='/home/horhik/code/nixconfig/overlays' +let g:netrw_dirhist_1='/home/horhik/.emacs.d' diff --git a/home/xmonad/.config/xmobar/bin/a b/home/xmonad/.config/xmobar/bin/a old mode 100644 new mode 100755 diff --git a/home/xmonad/.config/xmobar/bin/xmobarstatus b/home/xmonad/.config/xmobar/bin/xmobarstatus index 3975d9e..a57e078 100755 --- a/home/xmonad/.config/xmobar/bin/xmobarstatus +++ b/home/xmonad/.config/xmobar/bin/xmobarstatus @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh module GruvboxColors where diff --git a/home/xmonad/.config/xmobar/bin/xmobarstatus2 b/home/xmonad/.config/xmobar/bin/xmobarstatus2 index 47b910f..3fdb743 100755 --- a/home/xmonad/.config/xmobar/bin/xmobarstatus2 +++ b/home/xmonad/.config/xmobar/bin/xmobarstatus2 @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh backgroundColor="#282828" currentLineColor="#fabd2f" diff --git a/home/xmonad/.config/xmobar/config.hs b/home/xmonad/.config/xmobar/config.hs index eafc5d1..de5ea90 100644 --- a/home/xmonad/.config/xmobar/config.hs +++ b/home/xmonad/.config/xmobar/config.hs @@ -17,7 +17,7 @@ Config { , sepChar = "%" -- delineator between plugin names and straight text , alignSep = "][" -- separator between left-right alignment - , template = "——{%StdinReader%}—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————][%xmobarstatus%" + , template = "——{%StdinReader%}—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————][%/home/horhik/.config/xmobar/bin/xmobarstatus%" -- general behavior , lowerOnStart = False -- send to bottom of window stack on start diff --git a/home/xmonad/.config/xmobar/config_second.hs b/home/xmonad/.config/xmobar/config_second.hs index e7ab255..cef0063 100644 --- a/home/xmonad/.config/xmobar/config_second.hs +++ b/home/xmonad/.config/xmobar/config_second.hs @@ -16,7 +16,7 @@ -- layout , sepChar = "%" -- delineator between plugin names and straight text , alignSep = "][" -- separator between left-right alignment - , template = "--{%StdinReader%}————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————][%xmobarstatus2%" + , template = "--{%StdinReader%}————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————][%/home/horhik/.config/xmobar/bin/xmobarstatus2%" -- general behavior , lowerOnStart = False -- send to bottom of window stack on start diff --git a/home/xmonad/.xmonad/lib/GruvboxColors.hi b/home/xmonad/.xmonad/lib/GruvboxColors.hi index 25e0001b85d8e1be99e01ca7c8adbf49f79776a8..e774abf29b0200b4f83f1eccbf6c3cb028225ff6 100644 GIT binary patch delta 266 zcmZ3=vyeyl$(+~x3@jFg1||#)3@k-JtT<6jN9g<1UGEoMeckUc_1XGu_ud?O^<`qH zJ>#y4Q*{`xO*|B!AOKX&D9Rx4_)`17Q-^7RL2Eo@iB`tT7X$LKvo)0K&;zNdN!< delta 270 zcmZ3;vy?~d$(+~x3@jFg1}4lYm3a&dEM-8fI#F0hxMlU;eQWyr7Vl-8y<^gj4-@*X ztezNX&$w^mL>v1{Q|N UznP`Dr9n&u5TUwRfrXI?0ILU5F8}}l diff --git a/home/xmonad/.xmonad/xmonad.hs b/home/xmonad/.xmonad/xmonad.hs index bf13d5d..cd6c0dd 100644 --- a/home/xmonad/.xmonad/xmonad.hs +++ b/home/xmonad/.xmonad/xmonad.hs @@ -45,7 +45,7 @@ myFocusFollowsMouse :: Bool myFocusFollowsMouse = True myClickJustFocuses :: Bool myClickJustFocuses = False -myBorderWidth = 3 +myBorderWidth = 0 superKey = mod4Mask myModMask = superKey -- myWorkspaces = ["home 1","web 2","code 3","test 4","tkr 5","task 6","edit 7", "chat 8","book 9"] @@ -67,7 +67,7 @@ myKeys conf@(XConfig {XMonad.modMask = modm}) = M.fromList $ -- launch dmenu -- , ((modm, xK_p ), spawn ("dmenu_run " ++ " -fn '" ++ myDmenuFont ++ "' -nb '" ++ backgroundColor ++ "' -nf '" ++ selectionColor ++ "' -sb '"++ selectionColor ++"' -sf '"++foregroundSecondColor++"' -shb '"++ greenDarkerColor ++ "' -c "++" -l "++" 20 ")) -- launch emoji picker - , ((modm , xK_e ), spawn "emoji-menu") + , ((modm , xK_e ), spawn "rofimoji") , ((modm , xK_p ), spawn "rofi -show drun") , ((modm .|. shiftMask , xK_p ), spawn "rofi -show window") @@ -156,7 +156,7 @@ myKeys conf@(XConfig {XMonad.modMask = modm}) = M.fromList $ , ((modm .|. controlMask .|. shiftMask, xK_h), namedScratchpadAction myScratchpads "htop") , ((modm .|. shiftMask , xK_a), namedScratchpadAction myScratchpads "anki") , ((modm .|. shiftMask , xK_m), namedScratchpadAction myScratchpads "pulse") - , ((modm .|. shiftMask , xK_d), namedScratchpadAction myScratchpads "todoist") +-- , ((modm .|. shiftMask , xK_d), namedScratchpadAction myScratchpads "todoist") , ((modm .|. shiftMask , xK_n), namedScratchpadAction myScratchpads "rss_news") , ((modm .|. controlMask, xK_e), namedScratchpadAction myScratchpads "emacs") @@ -228,9 +228,9 @@ myMouseBindings (XConfig {XMonad.modMask = modm}) = M.fromList $ -- The available layouts. Note that each layout is separated by |||, -- which denotes layout choice. -- -defaultGapSize = 10 +defaultGapSize = 0 defaultGaps = gaps [(U,defaultGapSize), (R,defaultGapSize), (D, defaultGapSize), (L, defaultGapSize)] -defaultSpaces = spacingRaw True (Border 10 10 10 10) True (Border 10 10 10 10) True +defaultSpaces = spacingRaw True (Border 0 0 0 0) True (Border 0 0 0 0) True spacesAndGaps = defaultSpaces . defaultGaps myLayout = smartBorders . avoidStruts $ spacesAndGaps $ tiled ||| Mirror tiled ||| Full ||| simpleTabbed @@ -327,8 +327,8 @@ myScratchpads = [ l = (1 - w) / 2 -- centered left/right classTodoist = "TodoistDropdown" - titleTodoist = "Todoist" - spawnTodoist = "todoist" + titleTodoist = "Super Productivity" + spawnTodoist = "super-productivity" findTodoist = title =? titleTodoist manageTodoist = customFloating $ W.RationalRect l t w h where @@ -418,7 +418,6 @@ myStartupHook = do spawnOnce "nitrogen --restore &" -- spawnOnce "compton --config ~/.config/compton/compton.conf &" spawnOnce "picom --experimental-backends &" - spawnOnce "deadd-notification-center &" spawnOnce "setxkbmap us,ru &" spawnOnce "eww daemon" spawnOnce "nextcloud" @@ -433,7 +432,7 @@ myStartupHook = do -- spawnOnce ("cd /home/horhik/Freenet/downloads/fms; ./fms --daemon &") spawnOnce "xautolock -time 25 -locker i3lock-fancy-multimonitor -notifier 'xkb-switch -s us' &" spawnOnce "eval '$(ssh-agent -s)'; ssh-add ~/.ssh/id_rsa &" - spawnOnce "sleep 10; pulseaudio -k" + spawnOnce "xrandr --output HDMI-A-0 --left-of eDP &" ------------------------------------------------------------------------ -- Now run xmonad with all the defaults we set up. diff --git a/home/zsh/.zshrc b/home/zsh/.zshrc index 08c8e77..d34345c 100644 --- a/home/zsh/.zshrc +++ b/home/zsh/.zshrc @@ -1,110 +1,12 @@ -# If you come from bash you might have to change your $PATH. -# export PATH=$HOME/bin:/usr/local/bin:$PATH - -# Path to your oh-my-zsh installation. -export ZSH="/home/horhik/.oh-my-zsh" export CC=/usr/bin/clang - export CXX=/usr/bin/clang++ export _JAVA_AWT_WM_NONREPARENTING=1 export ANDROID_SDK_ROOT=/home/horhik/Android/Sdk/ export NDK_HOME=/home/horhik/Android/Sdk/ndk/22.0.7026061/ -# Set name of the theme to load --- if set to "random", it will -# load a random theme each time oh-my-zsh is loaded, in which case, -# to know which specific one was loaded, run: echo $RANDOM_THEME -# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes ZSH_THEME="cloud" - -# Set list of themes to pick from when loading at random -# Setting this variable when ZSH_THEME=random will cause zsh to load -# a theme from this variable instead of looking in $ZSH/themes/ -# If set to an empty array, this variable will have no effect. -# ZSH_THEME_RANDOM_CANDIDATES=( "robbyrussell" "agnoster" ) - -# Uncomment the following line to use case-sensitive completion. -# CASE_SENSITIVE="true" - -# Uncomment the following line to use hyphen-insensitive completion. -# Case-sensitive completion must be off. _ and - will be interchangeable. -# HYPHEN_INSENSITIVE="true" - -# Uncomment the following line to disable bi-weekly auto-update checks. -# DISABLE_AUTO_UPDATE="true" - -# Uncomment the following line to automatically update without prompting. -# DISABLE_UPDATE_PROMPT="true" - -# Uncomment the following line to change how often to auto-update (in days). -# export UPDATE_ZSH_DAYS=13 - -# Uncomment the following line if pasting URLs and other text is messed up. -# DISABLE_MAGIC_FUNCTIONS="true" - -# Uncomment the following line to disable colors in ls. -# DISABLE_LS_COLORS="true" - -# Uncomment the following line to disable auto-setting terminal title. -# DISABLE_AUTO_TITLE="true" - -# Uncomment the following line to enable command auto-correction. -# ENABLE_CORRECTION="true" - -# Uncomment the following line to display red dots whilst waiting for completion. -# COMPLETION_WAITING_DOTS="true" - -# Uncomment the following line if you want to disable marking untracked files -# under VCS as dirty. This makes repository status check for large repositories -# much, much faster. -# DISABLE_UNTRACKED_FILES_DIRTY="true" - -# Uncomment the following line if you want to change the command execution time -# stamp shown in the history command output. -# You can set one of the optional three formats: -# "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd" -# or set a custom format using the strftime function format specifications, -# see 'man strftime' for details. -# HIST_STAMPS="mm/dd/yyyy" - -# Would you like to use another custom folder than $ZSH/custom? -# ZSH_CUSTOM=/path/to/new-custom-folder - -# Which plugins would you like to load? -# Standard plugins can be found in $ZSH/plugins/ -# Custom plugins may be added to $ZSH_CUSTOM/plugins/ -# Example format: plugins=(rails git textmate ruby lighthouse) -# Add wisely, as too many plugins slow down shell startup. plugins=(git colorize colored-man-pages emoji rustup sudo zsh-syntax-highlighting zsh-autosuggestions zsh-completions) autoload -U compinit && compinit - -source $ZSH/oh-my-zsh.sh - -# User configuration - -# export MANPATH="/usr/local/man:$MANPATH" - -# You may need to manually set your language environment -# export LANG=en_US.UTF-8 - -# Preferred editor for local and remote sessions -# if [[ -n $SSH_CONNECTION ]]; then -# export EDITOR='vim' -# else -# export EDITOR='mvim' -# fi - -# Compilation flags -# export ARCHFLAGS="-arch x86_64" - -# Set personal aliases, overriding those provided by oh-my-zsh libs, -# plugins, and themes. Aliases can be placed here, though oh-my-zsh -# users are encouraged to define aliases within the ZSH_CUSTOM folder. -# For a full list of active aliases, run `alias`. -# -# Example aliases -# alias zshconfig="mate ~/.zshrc" -# alias ohmyzsh="mate ~/.oh-my-zsh" - export PATH=$HOME/.local/bin:$PATH export PATH=/usr/local/bin:$PATH export PATH=$HOME/.cargo/bin:$PATH @@ -112,21 +14,14 @@ export PATH=$HOME/.emacs.d/bin:$PATH export PATH=$HOME/Desktop:$PATH export PATH=/home/horhik/code/projects/potato-notify:$PATH export PATH="/root/.deno/bin:$PATH" - - alias vim=nvim alias vi=vim alias libvirtdaemon="sudo start-stop-daemon --start libvirtd" alias virtm="sudo start-stop-daemon --start virtlogd &; sudo start-stop-daemon --start libvirtd &; virt-manager &" alias clip=xclip -selection clipboard alias suspend="loginctl suspend" - -# The next line updates PATH for Yandex Cloud CLI. if [ -f '/home/horhik/yandex-cloud/path.bash.inc' ]; then source '/home/horhik/yandex-cloud/path.bash.inc'; fi - -# The next line enables shell command completion for yc. if [ -f '/home/horhik/yandex-cloud/completion.zsh.inc' ]; then source '/home/horhik/yandex-cloud/completion.zsh.inc'; fi - alias rd='rustc -g --emit="obj,link"' compile_and_run() { @@ -140,8 +35,8 @@ alias cc="cargo check" alias ct="cargo test" alias gc="git clone" alias gs="git status" -eval $(thefuck --alias) +alias vim="nvim" -pfetch +neofetch eval $(thefuck --alias) diff --git a/info.txt b/info.txt deleted file mode 100644 index e5b0654..0000000 --- a/info.txt +++ /dev/null @@ -1,2 +0,0 @@ -site with icons - https://fontawesome.com/v4.7.0/cheatsheet/ diff --git a/install b/install deleted file mode 100755 index ff95d55..0000000 --- a/install +++ /dev/null @@ -1,25 +0,0 @@ - -sudo pacman -S git fakeroot make patch gcc autoconf automake binutils bison stow zsh vim neovim -mkdir -p ~/Downloads/tmp; cd ~/Downloads/tmp; -pacman -S --needed git base-devel -git clone https://aur.archlinux.org/yay.git -cd yay -makepkg -si -sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" - -yay -S dunst firefox dwm surf dmenu st qutebrowser pulsemixer pkg-config variety alacritty compton-tryone-git ninja meson cmake libev libevdev uthash nerd-fonts-mononoki nerd-fonts tmux -# setup compositor -cd $HOME/Downloads/tmp -git clone https://github.com/ibhagwan/picom -cd picom -git submodule update --init --recursive -meson --buildtype=release . build -ninja -C build -sudo ninja -C build install - - ~/.vim/autoload/plug.vim --create-dirs \ - https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim - - - sh -c 'curl -fLo "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/autoload/plug.vim --create-dirs \ - https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim' diff --git a/install.sh b/install.sh index 7435604..34b0c04 100755 --- a/install.sh +++ b/install.sh @@ -7,7 +7,7 @@ cd yay makepkg -si sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" -yay -S dunst firefox dwm surf dmenu st qutebrowser pulsemixer pkg-config variety alacritty compton-tryone-git ninja meson cmake libev libevdev uthash nerd-fonts-mononoki nerd-fonts tmux feh xorg-xsetroot xkblayout-state flameshot cava rustfmt emacs playerctl rofi eww ttf-twemoji ttf-twemoji-color ttf-twemoji alacritty-themes anki clang xkblayout-state-git zathura redshift rustup pfetch xclip tree +yay -S dunst firefox dwm surf dmenu st qutebrowser pulsemixer pkg-config variety alacritty compton-tryone-git ninja meson cmake libev libevdev uthash nerd-fonts-mononoki nerd-fonts tmux feh xorg-xsetroot xkblayout-state flameshot cava rustfmt emacs playerctl rofi eww ttf-twemoji ttf-twemoji-color ttf-twemoji alacritty-themes anki clang xkblayout-state-git zathura redshift rustup pfetch xclip tree xorg-xbacklight # setup compositor cd $HOME/Downloads/tmp git clone https://github.com/ibhagwan/picom diff --git a/my_dwm/LICENSE b/my_dwm/LICENSE deleted file mode 100644 index d221f09..0000000 --- a/my_dwm/LICENSE +++ /dev/null @@ -1,37 +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 - -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/my_dwm/Makefile b/my_dwm/Makefile deleted file mode 100644 index 77bcbc0..0000000 --- a/my_dwm/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/my_dwm/README b/my_dwm/README deleted file mode 100644 index 95d4fd0..0000000 --- a/my_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/my_dwm/config.def.h b/my_dwm/config.def.h deleted file mode 100644 index 81577ff..0000000 --- a/my_dwm/config.def.h +++ /dev/null @@ -1,152 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* appearance */ -static const unsigned int borderpx = 3; /* border pixel of windows */ -static const unsigned int gappx = 10; /* gap pixel between 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[] = "Mononoki:size=12"; -static const char col_gray1[] = "#282828"; -static const char col_gray2[] = "#928374"; -static const char col_gray3[] = "#d5c4a1"; -static const char col_gray4[] = "#ebdbb2"; -static const char col_cyan[] = "#d65d0e"; -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[] = { - "pulsemixer", "-k", NULL, - "firefox", NULL, - "variety", NULL, - "redshift", NULL, - "picom", "--experimental-backends", "--detect-rounded-corners", NULL, - "picom", "--experimental-backends", "--detect-rounded-corners", NULL, - "setxkbmap","us,ru,fi",",winkeys","grp:alt_shift_toggle", NULL, - "$HOME/scripts/volume.sh", NULL, -/* "alacritty", "-t", "sp_volume", "-e", "$HOME/scripts/volume_launch.sh", NULL*/ - NULL /* terminate */ -}; - -/* tagging */ -static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - -/* launcher commands (They must be NULL terminated) */ -static const char* surf[] = { "surf", "duckduckgo.com", NULL }; - -static const Launcher launchers[] = { - /* command name to display */ - { surf, "surf" }, -}; - - -static const Rule rules[] = { - /* xprop(1): - * WM_CLASS(STRING) = instance, class - * WM_NAME(STRING) = title - */ - /* class instance title tags mask isfloating monitor scratch key */ -{ "Gimp", NULL, NULL, 0, 1, -1, 0 }, -{ "firefox", NULL, NULL, 1 << 8, 0, -1, 0 }, -{ NULL, NULL, "scratchpad", 0, 1, -1, 's' }, -{ NULL, NULL, "sp_volume", 0, 1, -1, 'v' }, - -}; - -/* 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 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, "-c", "-l", "20", NULL}; -static const char *termcmd[] = { "alacritty", NULL }; - -/*First arg only serves to match against key in rules*/ -static const char *scratchpadcmd[] = {"s", "alacritty", "-t", "scratchpad", NULL}; -static const char *sp_volume_control[] = {"v","st", "-t", "sp_volume","-e", "pulsemixer", NULL}; - - -static 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 } }, - { MODKEY, XK_minus, setgaps, {.i = -5 } }, - { MODKEY, XK_equal, setgaps, {.i = +5 } }, - { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, - /*SCRATCHPADS*/ - { MODKEY, XK_grave, togglescratch, {.v = scratchpadcmd } }, - { MODKEY|ShiftMask, XK_m, togglescratch, {.v = sp_volume_control } }, - 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 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/my_dwm/config.h b/my_dwm/config.h deleted file mode 100644 index 81577ff..0000000 --- a/my_dwm/config.h +++ /dev/null @@ -1,152 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* appearance */ -static const unsigned int borderpx = 3; /* border pixel of windows */ -static const unsigned int gappx = 10; /* gap pixel between 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[] = "Mononoki:size=12"; -static const char col_gray1[] = "#282828"; -static const char col_gray2[] = "#928374"; -static const char col_gray3[] = "#d5c4a1"; -static const char col_gray4[] = "#ebdbb2"; -static const char col_cyan[] = "#d65d0e"; -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[] = { - "pulsemixer", "-k", NULL, - "firefox", NULL, - "variety", NULL, - "redshift", NULL, - "picom", "--experimental-backends", "--detect-rounded-corners", NULL, - "picom", "--experimental-backends", "--detect-rounded-corners", NULL, - "setxkbmap","us,ru,fi",",winkeys","grp:alt_shift_toggle", NULL, - "$HOME/scripts/volume.sh", NULL, -/* "alacritty", "-t", "sp_volume", "-e", "$HOME/scripts/volume_launch.sh", NULL*/ - NULL /* terminate */ -}; - -/* tagging */ -static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - -/* launcher commands (They must be NULL terminated) */ -static const char* surf[] = { "surf", "duckduckgo.com", NULL }; - -static const Launcher launchers[] = { - /* command name to display */ - { surf, "surf" }, -}; - - -static const Rule rules[] = { - /* xprop(1): - * WM_CLASS(STRING) = instance, class - * WM_NAME(STRING) = title - */ - /* class instance title tags mask isfloating monitor scratch key */ -{ "Gimp", NULL, NULL, 0, 1, -1, 0 }, -{ "firefox", NULL, NULL, 1 << 8, 0, -1, 0 }, -{ NULL, NULL, "scratchpad", 0, 1, -1, 's' }, -{ NULL, NULL, "sp_volume", 0, 1, -1, 'v' }, - -}; - -/* 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 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, "-c", "-l", "20", NULL}; -static const char *termcmd[] = { "alacritty", NULL }; - -/*First arg only serves to match against key in rules*/ -static const char *scratchpadcmd[] = {"s", "alacritty", "-t", "scratchpad", NULL}; -static const char *sp_volume_control[] = {"v","st", "-t", "sp_volume","-e", "pulsemixer", NULL}; - - -static 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 } }, - { MODKEY, XK_minus, setgaps, {.i = -5 } }, - { MODKEY, XK_equal, setgaps, {.i = +5 } }, - { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, - /*SCRATCHPADS*/ - { MODKEY, XK_grave, togglescratch, {.v = scratchpadcmd } }, - { MODKEY|ShiftMask, XK_m, togglescratch, {.v = sp_volume_control } }, - 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 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/my_dwm/config.mk b/my_dwm/config.mk deleted file mode 100644 index 7084c33..0000000 --- a/my_dwm/config.mk +++ /dev/null @@ -1,38 +0,0 @@ -# dwm version -VERSION = 6.2 - -# 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 - -# includes and libs -INCS = -I${X11INC} -I${FREETYPEINC} -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} - -# flags -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} -CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS} -LDFLAGS = ${LIBS} - -# Solaris -#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" -#LDFLAGS = ${LIBS} - -# compiler and linker -CC = cc diff --git a/my_dwm/drw.c b/my_dwm/drw.c deleted file mode 100644 index cd899f8..0000000 --- a/my_dwm/drw.c +++ /dev/null @@ -1,438 +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."); - } - - /* Do not allow using color fonts. This is a workaround for a BadLength - * error from Xft with color glyphs. Modelled on the Xterm workaround. See - * https://bugzilla.redhat.com/show_bug.cgi?id=1498269 - * https://lists.suckless.org/dev/1701/30932.html - * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349 - * and lots more all over the internet. - */ - FcBool iscol; - if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) { - XftFontClose(drw->dpy, xfont); - return NULL; - } - - font = ecalloc(1, sizeof(Fnt)); - font->xfont = xfont; - font->pattern = pattern; - font->h = xfont->ascent + xfont->descent; - font->dpy = drw->dpy; - - return font; -} - -static void -xfont_free(Fnt *font) -{ - if (!font) - return; - if (font->pattern) - FcPatternDestroy(font->pattern); - XftFontClose(font->dpy, font->xfont); - free(font); -} - -Fnt* -drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount) -{ - Fnt *cur, *ret = NULL; - size_t i; - - if (!drw || !fonts) - return NULL; - - for (i = 1; i <= fontcount; i++) { - if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) { - cur->next = ret; - ret = cur; - } - } - return (drw->fonts = ret); -} - -void -drw_fontset_free(Fnt *font) -{ - if (font) { - drw_fontset_free(font->next); - xfont_free(font); - } -} - -void -drw_clr_create(Drw *drw, Clr *dest, const char *clrname) -{ - if (!drw || !dest || !clrname) - return; - - if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen), - DefaultColormap(drw->dpy, drw->screen), - clrname, dest)) - die("error, cannot allocate color '%s'", clrname); - - dest->pixel |= 0xff << 24; -} - -/* Wrapper to create color schemes. The caller has to call free(3) on the - * returned color scheme when done using it. */ -Clr * -drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount) -{ - size_t i; - Clr *ret; - - /* need at least two colors for a scheme */ - if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor)))) - return NULL; - - for (i = 0; i < clrcount; i++) - drw_clr_create(drw, &ret[i], clrnames[i]); - return ret; -} - -void -drw_setfontset(Drw *drw, Fnt *set) -{ - if (drw) - drw->fonts = set; -} - -void -drw_setscheme(Drw *drw, Clr *scm) -{ - if (drw) - drw->scheme = scm; -} - -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) -{ - char buf[1024]; - int ty; - unsigned int ew; - XftDraw *d = NULL; - Fnt *usedfont, *curfont, *nextfont; - size_t i, len; - int utf8strlen, utf8charlen, render = x || y || w || h; - long utf8codepoint = 0; - const char *utf8str; - FcCharSet *fccharset; - FcPattern *fcpattern; - FcPattern *match; - XftResult result; - int charexists = 0; - - if (!drw || (render && !drw->scheme) || !text || !drw->fonts) - return 0; - - if (!render) { - w = ~w; - } else { - XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel); - XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h); - d = XftDrawCreate(drw->dpy, drw->drawable, - DefaultVisual(drw->dpy, drw->screen), - DefaultColormap(drw->dpy, drw->screen)); - x += lpad; - w -= lpad; - } - - usedfont = drw->fonts; - while (1) { - utf8strlen = 0; - utf8str = text; - nextfont = NULL; - while (*text) { - utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ); - for (curfont = drw->fonts; curfont; curfont = curfont->next) { - charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint); - if (charexists) { - if (curfont == usedfont) { - utf8strlen += utf8charlen; - text += utf8charlen; - } else { - nextfont = curfont; - } - break; - } - } - - if (!charexists || nextfont) - break; - else - charexists = 0; - } - - if (utf8strlen) { - drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL); - /* shorten text if necessary */ - for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; len--) - drw_font_getexts(usedfont, utf8str, len, &ew, NULL); - - if (len) { - memcpy(buf, utf8str, len); - buf[len] = '\0'; - if (len < utf8strlen) - for (i = len; i && i > len - 3; buf[--i] = '.') - ; /* NOP */ - - if (render) { - ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent; - XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg], - usedfont->xfont, x, ty, (XftChar8 *)buf, len); - } - x += ew; - w -= ew; - } - } - - if (!*text) { - break; - } else if (nextfont) { - charexists = 0; - usedfont = nextfont; - } else { - /* Regardless of whether or not a fallback font is found, the - * character must be drawn. */ - charexists = 1; - - fccharset = FcCharSetCreate(); - FcCharSetAddChar(fccharset, utf8codepoint); - - if (!drw->fonts->pattern) { - /* Refer to the comment in xfont_create for more information. */ - die("the first font in the cache must be loaded from a font string."); - } - - fcpattern = FcPatternDuplicate(drw->fonts->pattern); - FcPatternAddCharSet(fcpattern, FC_CHARSET, fccharset); - FcPatternAddBool(fcpattern, FC_SCALABLE, FcTrue); - FcPatternAddBool(fcpattern, FC_COLOR, FcFalse); - - FcConfigSubstitute(NULL, fcpattern, FcMatchPattern); - FcDefaultSubstitute(fcpattern); - match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result); - - FcCharSetDestroy(fccharset); - FcPatternDestroy(fcpattern); - - if (match) { - usedfont = xfont_create(drw, NULL, match); - if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) { - for (curfont = drw->fonts; curfont->next; curfont = curfont->next) - ; /* NOP */ - curfont->next = usedfont; - } else { - xfont_free(usedfont); - usedfont = drw->fonts; - } - } - } - } - if (d) - XftDrawDestroy(d); - - return x + (render ? w : 0); -} - -void -drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h) -{ - if (!drw) - return; - - XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y); - XSync(drw->dpy, False); -} - -unsigned int -drw_fontset_getwidth(Drw *drw, const char *text) -{ - if (!drw || !drw->fonts || !text) - return 0; - return drw_text(drw, 0, 0, 0, 0, 0, text, 0); -} - -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/my_dwm/drw.h b/my_dwm/drw.h deleted file mode 100644 index 4bcd5ad..0000000 --- a/my_dwm/drw.h +++ /dev/null @@ -1,57 +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); -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/my_dwm/dwm b/my_dwm/dwm deleted file mode 100755 index 4661887287cbbca71c3b84c096452657e2b8e346..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71360 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

mk<~z{h68Gk%1Jhve+9q+Qamd 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 CviMm5 diff --git a/my_dwm/dwm.1 b/my_dwm/dwm.1 deleted file mode 100644 index ddc8321..0000000 --- a/my_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/my_dwm/dwm.c b/my_dwm/dwm.c deleted file mode 100644 index 6e9063a..0000000 --- a/my_dwm/dwm.c +++ /dev/null @@ -1,2288 +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; - int bw, oldbw; - unsigned int tags; - int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; - char scratchkey; - 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 */ - int gappx; /* gaps between windows */ - 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; - const char scratchkey; -} Rule; - -typedef struct { - const char** command; - const char* name; -} Launcher; - - -/* function declarations */ -static void applyrules(Client *c); -static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); -static void arrange(Monitor *m); -static void arrangemon(Monitor *m); -static void attach(Client *c); -static void attachstack(Client *c); -static void buttonpress(XEvent *e); -static void checkotherwm(void); -static void cleanup(void); -static void cleanupmon(Monitor *mon); -static void clientmessage(XEvent *e); -static void configure(Client *c); -static void configurenotify(XEvent *e); -static void configurerequest(XEvent *e); -static Monitor *createmon(void); -static void 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 *); -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 setgaps(const Arg *arg); -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 sigchld(int unused); -static void spawn(const Arg *arg); -static void spawnscratch(const Arg *arg); -static void tag(const Arg *arg); -static void tagmon(const Arg *arg); -static void tile(Monitor *); -static void togglebar(const Arg *arg); -static void togglefloating(const Arg *arg); -static void togglescratch(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); -static void autostart_exec(void); - -/* 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, blw = 0; /* bar geometry */ -static int lrpad; /* sum of left and right padding for text */ -static int (*xerrorxlib)(Display *, XErrorEvent *); -static unsigned int numlockmask = 0; -static void (*handler[LASTEvent]) (XEvent *) = { - [ButtonPress] = buttonpress, - [ClientMessage] = clientmessage, - [ConfigureRequest] = configurerequest, - [ConfigureNotify] = configurenotify, - [DestroyNotify] = destroynotify, - [EnterNotify] = enternotify, - [Expose] = expose, - [FocusIn] = focusin, - [KeyPress] = keypress, - [MappingNotify] = mappingnotify, - [MapRequest] = maprequest, - [MotionNotify] = motionnotify, - [PropertyNotify] = propertynotify, - [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]; }; - -/* dwm will keep pid's of processes from autostart array and kill them at quit */ -static pid_t *autostart_pids; -static size_t autostart_len; - -/* execute command from autostart array */ -static void -autostart_exec() { - const char *const *p; - size_t i = 0; - - /* count entries */ - for (p = autostart; *p; autostart_len++, p++) - while (*++p); - - autostart_pids = malloc(autostart_len * sizeof(pid_t)); - for (p = autostart; *p; i++, p++) { - if ((autostart_pids[i] = fork()) == 0) { - setsid(); - execvp(*p, (char *const *)p); - fprintf(stderr, "dwm: execvp %s\n", *p); - perror(" failed"); - _exit(EXIT_FAILURE); - } - /* skip arguments */ - while (*++p); - } -} - -/* 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; - c->scratchkey = 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; - c->scratchkey = r->scratchkey; - 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) { - /* 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; - goto execute_handler; - } else if (ev->x < x + blw) { - click = ClkLtSymbol; - goto execute_handler; - } - - x += blw; - - for(i = 0; i < LENGTH(launchers); i++) { - x += TEXTW(launchers[i].name); - - if (ev->x < x) { - Arg a; - a.v = launchers[i].command; - spawn(&a); - return; - } - } - - if (ev->x > selmon->ww - TEXTW(stext)) - click = ClkStatusText; - else - click = ClkWinTitle; - } else if ((c = wintoclient(ev->window))) { - focus(c); - restack(selmon); - XAllowEvents(dpy, ReplayPointer, CurrentTime); - click = ClkClientWin; - } - - execute_handler: - - for (i = 0; i < LENGTH(buttons); i++) - if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button - && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) - buttons[i].func(click == ClkTagBar && 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]); - 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 */)); - } 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; - 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) { - 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->gappx = gappx; - 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; - - /* 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 = blw = TEXTW(m->ltsymbol); - drw_setscheme(drw, scheme[SchemeNorm]); - x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); - - for (i = 0; i < LENGTH(launchers); i++) - { - w = TEXTW(launchers[i].name); - drw_text(drw, x, 0, w, bh, lrpad / 2, launchers[i].name, urg & 1 << i); - x += w; - } - - 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) - 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; - unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; - KeyCode code; - - XUngrabKey(dpy, AnyKey, AnyModifier, root); - for (i = 0; i < LENGTH(keys); i++) - if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) - for (j = 0; j < LENGTH(modifiers); j++) - XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, - True, GrabModeAsync, GrabModeAsync); - } -} - -void -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->mx + c->mon->mw) - c->x = c->mon->mx + c->mon->mw - WIDTH(c); - if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh) - c->y = c->mon->my + c->mon->mh - HEIGHT(c); - c->x = MAX(c->x, c->mon->mx); - /* only fix client y-offset, if the client center might cover the bar */ - c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx) - && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); - c->bw = borderpx; - - wc.border_width = c->bw; - if (((nexttiled(c->mon->clients) == c && !nexttiled(c->next)) - || &monocle == c->mon->lt[c->mon->sellt]->arrange)) - { - c->w = wc.width += c->bw * 2; - c->h = wc.height += c->bw * 2; - wc.border_width = 0; - } - 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)) - return; - if (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; - 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: - updatesizehints(c); - 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 -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; - 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; - } else if (!fullscreen && c->isfullscreen){ - XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, - PropModeReplace, (unsigned char*)0, 0); - c->isfullscreen = 0; - } -} - -void -setgaps(const Arg *arg) -{ - if ((arg->i == 0) || (selmon->gappx + arg->i < 0)) - selmon->gappx = 0; - else - selmon->gappx += arg->i; - arrange(selmon); -} - -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; - - /* clean up any zombies immediately */ - sigchld(0); - - /* init screen */ - screen = DefaultScreen(dpy); - sw = DisplayWidth(dpy, screen); - sh = DisplayHeight(dpy, screen); - root = RootWindow(dpy, screen); - drw = drw_create(dpy, screen, root, sw, sh); - if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) - die("no fonts could be loaded."); - lrpad = drw->fonts->h; - bh = drw->fonts->h + 2; - 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) - 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 -sigchld(int unused) -{ - pid_t pid; - - if (signal(SIGCHLD, sigchld) == SIG_ERR) - die("can't install SIGCHLD handler:"); - 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 -spawn(const Arg *arg) -{ - if (arg->v == dmenucmd) - dmenumon[0] = '0' + selmon->num; - if (fork() == 0) { - if (dpy) - close(ConnectionNumber(dpy)); - setsid(); - execvp(((char **)arg->v)[0], (char **)arg->v); - fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]); - perror(" failed"); - exit(EXIT_SUCCESS); - } -} - -void spawnscratch(const Arg *arg) -{ - if (fork() == 0) { - if (dpy) - close(ConnectionNumber(dpy)); - setsid(); - execvp(((char **)arg->v)[1], ((char **)arg->v)+1); - fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[1]); - perror(" failed"); - exit(EXIT_SUCCESS); - } -} - - -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, ns; - Client *c; - - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - if (n == 0) - return; - if(n == 1){ - c = nexttiled(m->clients); - resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); - return; - } - - if (n > m->nmaster){ - mw = m->nmaster ? m->ww * m->mfact : 0; - ns = m->nmaster > 0 ? 2 : 1; - } - else{ - mw = m->ww - m->gappx; - ns = 1; - } - for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if (i < m->nmaster) { - h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx; - resize(c, m->wx + m->gappx, m->wy + my, mw - 2*c->bw - m->gappx*(5-ns)/2, h - 2*c->bw, 0); - if(my + HEIGHT(c) + m->gappx < m->wh) - my += HEIGHT(c) + m->gappx; - } else { - h = (m->wh - ty) / (n - i) - m->gappx; - resize(c, m->wx + mw + m->gappx/ns, m->wy + ty, m->ww - mw - (2*c->bw) - m->gappx*(5-ns)/2, h - 2*c->bw, 0); - if(ty + HEIGHT(c) + m->gappx < m->wh) - ty += HEIGHT(c) + m->gappx; - } -} - -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; - 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 -togglescratch(const Arg *arg) -{ - Client *c; - unsigned int found = 0; - - for (c = selmon->clients; c && !(found = c->scratchkey == ((char**)arg->v)[0][0]); c = c->next); - if (found) { - c->tags = ISVISIBLE(c) ? 0 : selmon->tagset[selmon->seltags]; - focus(NULL); - arrange(selmon); - - if (ISVISIBLE(c)) { - focus(c); - restack(selmon); - } - - } else{ - spawnscratch(arg); - } -} - -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); - 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() -{ - 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; - if (n <= nn) { /* new monitors available */ - for (i = 0; i < (nn - n); i++) { - for (m = mons; m && m->next; m = m->next); - if (m) - m->next = createmon(); - else - mons = createmon(); - } - for (i = 0, m = mons; i < nn && m; m = m->next, i++) - if (i >= n - || unique[i].x_org != m->mx || unique[i].y_org != m->my - || unique[i].width != m->mw || unique[i].height != m->mh) - { - dirty = 1; - m->num = i; - m->mx = m->wx = unique[i].x_org; - m->my = m->wy = unique[i].y_org; - m->mw = m->ww = unique[i].width; - m->mh = m->wh = unique[i].height; - updatebarpos(m); - } - } else { /* less monitors available nn < n */ - for (i = nn; i < n; i++) { - for (m = mons; m && m->next; m = m->next); - while ((c = m->clients)) { - dirty = 1; - m->clients = c->next; - detachstack(c); - c->mon = mons; - attach(c); - 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); -} - -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 - || (selmon->sel && selmon->sel->isfloating)) - return; - if (c == nexttiled(selmon->clients)) - if (!c || !(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/my_dwm/dwm.png b/my_dwm/dwm.png deleted file mode 100644 index b1f9ba7e5f4cc7350ee2392ebcea5fcbe00fb49b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 373 zcmeAS@N?(olHy`uVBq!ia0vp^2Y@($g9*gC@m3f}u_bxCyDx`7I;J! zGca%iWx0hJ8D`Cq01C2~c>21sUt<^MF=V?Ztt9{yk}YwKC~?lu%}vcKVQ?-=O)N=G zQ7F$W$xsN%NL6t6^bL5QqM8R(c+=CxF{I+w+q;fj4F)_6j>`Z3pZ>_($QEQ&92OXP z%lpEKGwG8$G-U1H{@Y%;mx-mNK|p|siBVAj$Z~Mt-~h6K0!}~{PyozQ07(f5fTdVi zm=-zT`NweeJ#%S&{fequZGmkDDC*%x$$Sa*fAP=$`nJkhx1Y~k<8b2;Hq)FOdV=P$ q&oWzoxz_&nv&n0)xBzV8k*jsxheTIy&cCY600f?{elF{r5}E*x)opSB diff --git a/my_dwm/patches/dwm-autostart-20161205-bb3bd6f.diff b/my_dwm/patches/dwm-autostart-20161205-bb3bd6f.diff deleted file mode 100644 index 6f11eaf..0000000 --- a/my_dwm/patches/dwm-autostart-20161205-bb3bd6f.diff +++ /dev/null @@ -1,39 +0,0 @@ -commit 5918623c5bd7fda155bf9dc3d33890c4ae1722d0 -Author: Simon Bremer -Date: Thu Dec 22 17:31:07 2016 +0100 - - Applied and fixed autostart patch for previous version; - -diff --git a/dwm.c b/dwm.c -index d27cb67..066ed71 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -194,6 +194,7 @@ 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 runAutostart(void); - static void scan(void); - static int sendevent(Client *c, Atom proto); - static void sendmon(Client *c, Monitor *m); -@@ -1386,6 +1387,12 @@ run(void) - } - - void -+runAutostart(void) { -+ system("cd ~/.dwm; ./autostart_blocking.sh"); -+ system("cd ~/.dwm; ./autostart.sh &"); -+} -+ -+void - scan(void) - { - unsigned int i, num; -@@ -2145,6 +2152,7 @@ main(int argc, char *argv[]) - checkotherwm(); - setup(); - scan(); -+ runAutostart(); - run(); - cleanup(); - XCloseDisplay(dpy); diff --git a/my_dwm/patches/dwm-autostart-20200610-cb3f58a.diff b/my_dwm/patches/dwm-autostart-20200610-cb3f58a.diff deleted file mode 100644 index 7e17424..0000000 --- a/my_dwm/patches/dwm-autostart-20200610-cb3f58a.diff +++ /dev/null @@ -1,179 +0,0 @@ -From 37e970479dc5d40e57fc0cbfeaa5e39941483237 Mon Sep 17 00:00:00 2001 -From: Gan Ainm -Date: Wed, 10 Jun 2020 10:59:02 +0000 -Subject: [PATCH] dwm-xdgautostart-6.2.diff - -=================================================================== ---- - dwm.1 | 23 +++++++++++++++++ - dwm.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 105 insertions(+) - -diff --git a/dwm.1 b/dwm.1 -index 13b3729..9533aa6 100644 ---- a/dwm.1 -+++ b/dwm.1 -@@ -30,6 +30,14 @@ top left corner. The tags which are applied to one or more windows are - indicated with an empty square in the top left corner. - .P - dwm draws a small border around windows to indicate the focus state. -+.P -+On start, dwm can start additional programs that may be specified in two special -+shell scripts (see the FILES section below), autostart_blocking.sh and -+autostart.sh. The former is executed first and dwm will wait for its -+termination before starting. The latter is executed in the background before -+dwm enters its handler loop. -+.P -+Either of these files may be omitted. - .SH OPTIONS - .TP - .B \-v -@@ -152,6 +160,21 @@ Toggles focused window between floating and tiled state. - .TP - .B Mod1\-Button3 - Resize focused window while dragging. Tiled windows will be toggled to the floating state. -+.SH FILES -+The files containing programs to be started along with dwm are searched for in -+the following directories: -+.IP "1. $XDG_DATA_HOME/dwm" -+.IP "2. $HOME/.local/share/dwm" -+.IP "3. $HOME/.dwm" -+.P -+The first existing directory is scanned for any of the autostart files below. -+.TP 15 -+autostart.sh -+This file is started as a shell background process before dwm enters its handler -+loop. -+.TP 15 -+autostart_blocking.sh -+This file is started before any autostart.sh; dwm waits for its termination. - .SH CUSTOMIZATION - dwm is customized by creating a custom config.h and (re)compiling the source - code. This keeps it fast, secure and simple. -diff --git a/dwm.c b/dwm.c -index 4465af1..2156b49 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -193,6 +194,7 @@ 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 runautostart(void); - static void scan(void); - static int sendevent(Client *c, Atom proto); - static void sendmon(Client *c, Monitor *m); -@@ -235,7 +237,11 @@ static int xerrorstart(Display *dpy, XErrorEvent *ee); - static void zoom(const Arg *arg); - - /* variables */ -+static const char autostartblocksh[] = "autostart_blocking.sh"; -+static const char autostartsh[] = "autostart.sh"; - static const char broken[] = "broken"; -+static const char dwmdir[] = "dwm"; -+static const char localshare[] = ".local/share"; - static char stext[256]; - static int screen; - static int sw, sh; /* X display screen geometry width, height */ -@@ -1380,6 +1386,83 @@ run(void) - handler[ev.type](&ev); /* call handler */ - } - -+void -+runautostart(void) -+{ -+ char *pathpfx; -+ char *path; -+ char *xdgdatahome; -+ char *home; -+ struct stat sb; -+ -+ if ((home = getenv("HOME")) == NULL) -+ /* this is almost impossible */ -+ return; -+ -+ /* if $XDG_DATA_HOME is set and not empty, use $XDG_DATA_HOME/dwm, -+ * otherwise use ~/.local/share/dwm as autostart script directory -+ */ -+ xdgdatahome = getenv("XDG_DATA_HOME"); -+ if (xdgdatahome != NULL && *xdgdatahome != '\0') { -+ /* space for path segments, separators and nul */ -+ pathpfx = ecalloc(1, strlen(xdgdatahome) + strlen(dwmdir) + 2); -+ -+ if (sprintf(pathpfx, "%s/%s", xdgdatahome, dwmdir) <= 0) { -+ free(pathpfx); -+ return; -+ } -+ } else { -+ /* space for path segments, separators and nul */ -+ pathpfx = ecalloc(1, strlen(home) + strlen(localshare) -+ + strlen(dwmdir) + 3); -+ -+ if (sprintf(pathpfx, "%s/%s/%s", home, localshare, dwmdir) < 0) { -+ free(pathpfx); -+ return; -+ } -+ } -+ -+ /* check if the autostart script directory exists */ -+ if (! (stat(pathpfx, &sb) == 0 && S_ISDIR(sb.st_mode))) { -+ /* the XDG conformant path does not exist or is no directory -+ * so we try ~/.dwm instead -+ */ -+ char *pathpfx_new = realloc(pathpfx, strlen(home) + strlen(dwmdir) + 3); -+ if(pathpfx_new == NULL) { -+ free(pathpfx); -+ return; -+ } -+ pathpfx = pathpfx_new; -+ -+ if (sprintf(pathpfx, "%s/.%s", home, dwmdir) <= 0) { -+ free(pathpfx); -+ return; -+ } -+ } -+ -+ /* try the blocking script first */ -+ path = ecalloc(1, strlen(pathpfx) + strlen(autostartblocksh) + 2); -+ if (sprintf(path, "%s/%s", pathpfx, autostartblocksh) <= 0) { -+ free(path); -+ free(pathpfx); -+ } -+ -+ if (access(path, X_OK) == 0) -+ system(path); -+ -+ /* now the non-blocking script */ -+ if (sprintf(path, "%s/%s", pathpfx, autostartsh) <= 0) { -+ free(path); -+ free(pathpfx); -+ } -+ -+ if (access(path, X_OK) == 0) -+ system(strcat(path, " &")); -+ -+ free(pathpfx); -+ free(path); -+} -+ - void - scan(void) - { -@@ -2142,6 +2223,7 @@ main(int argc, char *argv[]) - die("pledge"); - #endif /* __OpenBSD__ */ - scan(); -+ runautostart(); - run(); - cleanup(); - XCloseDisplay(dpy); --- -2.27.0 - diff --git a/my_dwm/patches/dwm-cool-autostart-6.2.diff b/my_dwm/patches/dwm-cool-autostart-6.2.diff deleted file mode 100644 index 84a93ea..0000000 --- a/my_dwm/patches/dwm-cool-autostart-6.2.diff +++ /dev/null @@ -1,116 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 1c0b587..ed056a4 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -18,6 +18,11 @@ static const char *colors[][3] = { - [SchemeSel] = { col_gray4, col_cyan, col_cyan }, - }; - -+static const char *const autostart[] = { -+ "st", NULL, -+ NULL /* terminate */ -+}; -+ - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - -diff --git a/dwm.c b/dwm.c -index 9fd0286..1facd56 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -234,6 +234,7 @@ 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 const char broken[] = "broken"; -@@ -275,6 +276,34 @@ static Window root, wmcheckwin; - /* 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; -+ size_t i = 0; -+ -+ /* count entries */ -+ for (p = autostart; *p; autostart_len++, p++) -+ while (*++p); -+ -+ autostart_pids = malloc(autostart_len * sizeof(pid_t)); -+ for (p = autostart; *p; i++, p++) { -+ if ((autostart_pids[i] = fork()) == 0) { -+ setsid(); -+ execvp(*p, (char *const *)p); -+ fprintf(stderr, "dwm: execvp %s\n", *p); -+ perror(" failed"); -+ _exit(EXIT_FAILURE); -+ } -+ /* skip arguments */ -+ while (*++p); -+ } -+} -+ - /* function implementations */ - void - applyrules(Client *c) -@@ -1249,6 +1278,16 @@ propertynotify(XEvent *e) - 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; - } - -@@ -1632,9 +1671,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 -@@ -2139,6 +2194,7 @@ main(int argc, char *argv[]) - if (!(dpy = XOpenDisplay(NULL))) - die("dwm: cannot open display"); - checkotherwm(); -+ autostart_exec(); - setup(); - #ifdef __OpenBSD__ - if (pledge("stdio rpath proc exec", NULL) == -1) - diff --git a/my_dwm/patches/dwm-fakefullscreen-20170508-ceac8c9.diff b/my_dwm/patches/dwm-fakefullscreen-20170508-ceac8c9.diff deleted file mode 100644 index 0c15db4..0000000 --- a/my_dwm/patches/dwm-fakefullscreen-20170508-ceac8c9.diff +++ /dev/null @@ -1,92 +0,0 @@ -diff --git a/dwm.c b/dwm.c -index a5ce993..42d2049 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -522,7 +522,7 @@ clientmessage(XEvent *e) - 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))); -+ || cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */)); - } else if (cme->message_type == netatom[NetActiveWindow]) { - if (c != selmon->sel && !c->isurgent) - seturgent(c, 1); -@@ -552,7 +552,6 @@ void - configurenotify(XEvent *e) - { - Monitor *m; -- Client *c; - XConfigureEvent *ev = &e->xconfigure; - int dirty; - -@@ -565,9 +564,6 @@ configurenotify(XEvent *e) - 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); -@@ -1145,8 +1141,6 @@ movemouse(const Arg *arg) - - if (!(c = selmon->sel)) - return; -- if (c->isfullscreen) /* no support moving fullscreen windows by mouse */ -- return; - restack(selmon); - ocx = c->x; - ocy = c->y; -@@ -1300,8 +1294,6 @@ resizemouse(const Arg *arg) - - if (!(c = selmon->sel)) - return; -- if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */ -- return; - restack(selmon); - ocx = c->x; - ocy = c->y; -@@ -1478,24 +1470,10 @@ setfullscreen(Client *c, int fullscreen) - 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); - } - } - -@@ -1620,7 +1598,7 @@ showhide(Client *c) - 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) -+ if (!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) - resize(c, c->x, c->y, c->w, c->h, 0); - showhide(c->snext); - } else { -@@ -1712,8 +1690,6 @@ 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, diff --git a/my_dwm/patches/dwm-floatrules-6.2.diff b/my_dwm/patches/dwm-floatrules-6.2.diff deleted file mode 100644 index 5dab1e0..0000000 --- a/my_dwm/patches/dwm-floatrules-6.2.diff +++ /dev/null @@ -1,64 +0,0 @@ -diff -u dwm/config.def.h dwmnew/config.def.h ---- dwm/config.def.h 2020-03-01 19:10:06.676821764 +1300 -+++ dwmnew/config.def.h 2020-03-01 19:29:26.276901430 +1300 -@@ -26,9 +26,9 @@ - * 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 }, -+ /* class instance title tags mask isfloating monitor float x,y,w,h floatborderpx*/ -+ { "Gimp", NULL, NULL, 0, 1, -1, 50,50,500,500, 5 }, -+ { "Firefox", NULL, NULL, 1 << 8, 0, -1, 50,50,500,500, 5 }, - }; - - /* layout(s) */ -Only in dwmnew: config.h -Only in dwmnew: drw.o -diff -u dwm/dwm.c dwmnew/dwm.c ---- dwm/dwm.c 2020-03-01 19:10:06.680155097 +1300 -+++ dwmnew/dwm.c 2020-03-01 19:28:26.793564016 +1300 -@@ -93,6 +93,7 @@ - int bw, oldbw; - unsigned int tags; - int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; -+ int floatborderpx; - Client *next; - Client *snext; - Monitor *mon; -@@ -139,6 +140,8 @@ - unsigned int tags; - int isfloating; - int monitor; -+ int floatx, floaty, floatw, floath; -+ int floatborderpx; - } Rule; - - /* function declarations */ -@@ -299,6 +302,13 @@ - { - c->isfloating = r->isfloating; - c->tags |= r->tags; -+ c->floatborderpx = r->floatborderpx; -+ if (r->isfloating) { -+ c->x = r->floatx; -+ c->y = r->floaty; -+ c->w = r->floatw; -+ c->h = r->floath; -+ } - for (m = mons; m && m->num != r->monitor; m = m->next); - if (m) - c->mon = m; -@@ -1281,7 +1291,10 @@ - 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; -+ if (c->isfloating) -+ wc.border_width = c->floatborderpx; -+ else -+ wc.border_width = c->bw; - XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); - configure(c); - XSync(dpy, False); diff --git a/my_dwm/patches/dwm-gaps-6.0.diff b/my_dwm/patches/dwm-gaps-6.0.diff deleted file mode 100644 index 80e1c8d..0000000 --- a/my_dwm/patches/dwm-gaps-6.0.diff +++ /dev/null @@ -1,53 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 77ff358..a4e496b 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -9,6 +9,7 @@ static const char selbordercolor[] = "#005577"; - static const char selbgcolor[] = "#005577"; - static const char selfgcolor[] = "#eeeeee"; - static const unsigned int borderpx = 1; /* border pixel of windows */ -+static const unsigned int gappx = 1; /* gap pixel between windows */ - static const unsigned int snap = 32; /* snap pixel */ - static const Bool showbar = True; /* False means no bar */ - static const Bool topbar = True; /* False means bottom bar */ -diff --git a/dwm.c b/dwm.c -index 1d78655..6cc96ff 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -1703,7 +1703,7 @@ textnw(const char *text, unsigned int len) { - - void - tile(Monitor *m) { -- unsigned int i, n, h, mw, my, ty; -+ unsigned int i, n, h, r, g = 0, mw, my, ty; - Client *c; - - for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); -@@ -1711,19 +1711,21 @@ tile(Monitor *m) { - return; - - if(n > m->nmaster) -- mw = m->nmaster ? m->ww * m->mfact : 0; -+ mw = m->nmaster ? (m->ww - (g = gappx)) * 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); -+ r = MIN(n, m->nmaster) - i; -+ h = (m->wh - my - gappx * (r - 1)) / r; - resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), False); -- my += HEIGHT(c); -+ my += HEIGHT(c) + gappx; - } - 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), False); -- ty += HEIGHT(c); -+ r = n - i; -+ h = (m->wh - ty - gappx * (r - 1)) / r; -+ resize(c, m->wx + mw + g, m->wy + ty, m->ww - mw - g - (2*c->bw), h - (2*c->bw), False); -+ ty += HEIGHT(c) + gappx; - } - } - diff --git a/my_dwm/patches/dwm-launchers-20200527-f09418b.diff b/my_dwm/patches/dwm-launchers-20200527-f09418b.diff deleted file mode 100644 index a683636..0000000 --- a/my_dwm/patches/dwm-launchers-20200527-f09418b.diff +++ /dev/null @@ -1,101 +0,0 @@ -From 6b5e23cdf8108a9033acc7c21c8926c0c72647fc Mon Sep 17 00:00:00 2001 -From: Adham Zahran -Date: Wed, 27 May 2020 18:07:57 +0200 -Subject: [PATCH] Top bar now has buttons that launches programs - ---- - config.def.h | 8 ++++++++ - dwm.c | 36 ++++++++++++++++++++++++++++++++++-- - 2 files changed, 42 insertions(+), 2 deletions(-) - -diff --git a/config.def.h b/config.def.h -index 1c0b587..9231cd5 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -21,6 +21,14 @@ static const char *colors[][3] = { - /* tagging */ - static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; - -+/* launcher commands (They must be NULL terminated) */ -+static const char* surf[] = { "surf", "duckduckgo.com", NULL }; -+ -+static const Launcher launchers[] = { -+ /* command name to display */ -+ { surf, "surf" }, -+}; -+ - static const Rule rules[] = { - /* xprop(1): - * WM_CLASS(STRING) = instance, class -diff --git a/dwm.c b/dwm.c -index 9fd0286..79e7e20 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -141,6 +141,11 @@ typedef struct { - int monitor; - } Rule; - -+typedef struct { -+ const char** command; -+ const char* name; -+} Launcher; -+ - /* function declarations */ - static void applyrules(Client *c); - static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); -@@ -438,9 +443,26 @@ buttonpress(XEvent *e) - if (i < LENGTH(tags)) { - click = ClkTagBar; - arg.ui = 1 << i; -- } else if (ev->x < x + blw) -+ goto execute_handler; -+ } else if (ev->x < x + blw) { - click = ClkLtSymbol; -- else if (ev->x > selmon->ww - TEXTW(stext)) -+ goto execute_handler; -+ } -+ -+ x += blw; -+ -+ for(i = 0; i < LENGTH(launchers); i++) { -+ x += TEXTW(launchers[i].name); -+ -+ if (ev->x < x) { -+ Arg a; -+ a.v = launchers[i].command; -+ spawn(&a); -+ return; -+ } -+ } -+ -+ if (ev->x > selmon->ww - TEXTW(stext)) - click = ClkStatusText; - else - click = ClkWinTitle; -@@ -450,6 +472,9 @@ buttonpress(XEvent *e) - XAllowEvents(dpy, ReplayPointer, CurrentTime); - click = ClkClientWin; - } -+ -+execute_handler: -+ - for (i = 0; i < LENGTH(buttons); i++) - if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button - && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) -@@ -728,6 +753,13 @@ drawbar(Monitor *m) - w = blw = TEXTW(m->ltsymbol); - drw_setscheme(drw, scheme[SchemeNorm]); - x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); -+ -+ for (i = 0; i < LENGTH(launchers); i++) -+ { -+ w = TEXTW(launchers[i].name); -+ drw_text(drw, x, 0, w, bh, lrpad / 2, launchers[i].name, urg & 1 << i); -+ x += w; -+ } - - if ((w = m->ww - tw - x) > bh) { - if (m->sel) { --- -2.17.1 - diff --git a/my_dwm/patches/dwm-namedscratchpads-6.2.diff b/my_dwm/patches/dwm-namedscratchpads-6.2.diff deleted file mode 100644 index d007118..0000000 --- a/my_dwm/patches/dwm-namedscratchpads-6.2.diff +++ /dev/null @@ -1,138 +0,0 @@ -diff '--color=auto' -up dwm-6.2/config.def.h dwm-6.2-new/config.def.h ---- dwm-6.2/config.def.h 2019-02-02 12:55:28.000000000 +0000 -+++ dwm-6.2-new/config.def.h 2020-04-26 13:51:06.713332746 +0100 -@@ -26,9 +26,10 @@ static const Rule rules[] = { - * 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 }, -+ /* class instance title tags mask isfloating monitor scratch key */ -+ { "Gimp", NULL, NULL, 0, 1, -1, 0 }, -+ { "firefox", NULL, NULL, 1 << 8, 0, -1, 0 }, -+ { NULL, NULL, "scratchpad", 0, 1, -1, 's' }, - }; - - /* layout(s) */ -@@ -59,10 +60,14 @@ static char dmenumon[2] = "0"; /* compon - 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 }; - -+/*First arg only serves to match against key in rules*/ -+static const char *scratchpadcmd[] = {"s", "st", "-t", "scratchpad", NULL}; -+ - static Key keys[] = { - /* modifier key function argument */ - { MODKEY, XK_p, spawn, {.v = dmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, -+ { MODKEY, XK_grave, togglescratch, {.v = scratchpadcmd } }, - { MODKEY, XK_b, togglebar, {0} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, -diff '--color=auto' -up dwm-6.2/dwm.c dwm-6.2-new/dwm.c ---- dwm-6.2/dwm.c 2019-02-02 12:55:28.000000000 +0000 -+++ dwm-6.2-new/dwm.c 2020-04-26 13:55:56.820584361 +0100 -@@ -93,6 +93,7 @@ struct Client { - int bw, oldbw; - unsigned int tags; - int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; -+ char scratchkey; - Client *next; - Client *snext; - Monitor *mon; -@@ -139,6 +140,7 @@ typedef struct { - unsigned int tags; - int isfloating; - int monitor; -+ const char scratchkey; - } Rule; - - /* function declarations */ -@@ -206,11 +208,13 @@ static void seturgent(Client *c, int urg - static void showhide(Client *c); - static void sigchld(int unused); - static void spawn(const Arg *arg); -+static void spawnscratch(const Arg *arg); - static void tag(const Arg *arg); - static void tagmon(const Arg *arg); - static void tile(Monitor *); - static void togglebar(const Arg *arg); - static void togglefloating(const Arg *arg); -+static void togglescratch(const Arg *arg); - static void toggletag(const Arg *arg); - static void toggleview(const Arg *arg); - static void unfocus(Client *c, int setfocus); -@@ -287,6 +291,7 @@ applyrules(Client *c) - /* rule matching */ - c->isfloating = 0; - c->tags = 0; -+ c->scratchkey = 0; - XGetClassHint(dpy, c->win, &ch); - class = ch.res_class ? ch.res_class : broken; - instance = ch.res_name ? ch.res_name : broken; -@@ -299,6 +304,7 @@ applyrules(Client *c) - { - c->isfloating = r->isfloating; - c->tags |= r->tags; -+ c->scratchkey = r->scratchkey; - for (m = mons; m && m->num != r->monitor; m = m->next); - if (m) - c->mon = m; -@@ -308,6 +314,7 @@ applyrules(Client *c) - 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]; - } - -@@ -1652,6 +1659,19 @@ spawn(const Arg *arg) - } - } - -+void spawnscratch(const Arg *arg) -+{ -+ if (fork() == 0) { -+ if (dpy) -+ close(ConnectionNumber(dpy)); -+ setsid(); -+ execvp(((char **)arg->v)[1], ((char **)arg->v)+1); -+ fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[1]); -+ perror(" failed"); -+ exit(EXIT_SUCCESS); -+ } -+} -+ - void - tag(const Arg *arg) - { -@@ -1720,6 +1740,28 @@ togglefloating(const Arg *arg) - } - - void -+togglescratch(const Arg *arg) -+{ -+ Client *c; -+ unsigned int found = 0; -+ -+ for (c = selmon->clients; c && !(found = c->scratchkey == ((char**)arg->v)[0][0]); c = c->next); -+ if (found) { -+ c->tags = ISVISIBLE(c) ? 0 : selmon->tagset[selmon->seltags]; -+ focus(NULL); -+ arrange(selmon); -+ -+ if (ISVISIBLE(c)) { -+ focus(c); -+ restack(selmon); -+ } -+ -+ } else{ -+ spawnscratch(arg); -+ } -+} -+ -+void - toggletag(const Arg *arg) - { - unsigned int newtags; diff --git a/my_dwm/patches/dwm-ru_gaps-6.2.diff b/my_dwm/patches/dwm-ru_gaps-6.2.diff deleted file mode 100644 index 61f25f5..0000000 --- a/my_dwm/patches/dwm-ru_gaps-6.2.diff +++ /dev/null @@ -1,127 +0,0 @@ -diff -up a/config.def.h b/config.def.h ---- a/config.def.h 2020-04-17 13:37:50.926942626 +0200 -+++ b/config.def.h 2020-04-25 15:24:56.722215722 +0200 -@@ -2,6 +2,7 @@ - - /* appearance */ - static const unsigned int borderpx = 1; /* border pixel of windows */ -+static const int gappx = 5; /* gaps between 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 */ -@@ -84,6 +85,9 @@ static Key keys[] = { - { MODKEY, XK_period, focusmon, {.i = +1 } }, - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, - { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, -+ { MODKEY, XK_minus, setgaps, {.i = -5 } }, -+ { MODKEY, XK_equal, setgaps, {.i = +5 } }, -+ { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, - TAGKEYS( XK_1, 0) - TAGKEYS( XK_2, 1) - TAGKEYS( XK_3, 2) -diff -up a/dwm.c b/dwm.c ---- a/dwm.c 2020-04-17 13:37:50.926942626 +0200 -+++ b/dwm.c 2020-04-25 15:29:37.664175514 +0200 -@@ -119,6 +119,7 @@ struct Monitor { - int by; /* bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ -+ int gappx; /* gaps between windows */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; -@@ -199,6 +200,7 @@ static void sendmon(Client *c, Monitor * - static void setclientstate(Client *c, long state); - static void setfocus(Client *c); - static void setfullscreen(Client *c, int fullscreen); -+static void setgaps(const Arg *arg); - static void setlayout(const Arg *arg); - static void setmfact(const Arg *arg); - static void setup(void); -@@ -638,6 +640,7 @@ createmon(void) - m->nmaster = nmaster; - m->showbar = showbar; - m->topbar = topbar; -+ m->gappx = gappx; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -@@ -1282,6 +1285,13 @@ resizeclient(Client *c, int x, int y, in - c->oldw = c->w; c->w = wc.width = w; - c->oldh = c->h; c->h = wc.height = h; - wc.border_width = c->bw; -+ if (((nexttiled(c->mon->clients) == c && !nexttiled(c->next)) -+ || &monocle == c->mon->lt[c->mon->sellt]->arrange)) -+ { -+ c->w = wc.width += c->bw * 2; -+ c->h = wc.height += c->bw * 2; -+ wc.border_width = 0; -+ } - XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); - configure(c); - XSync(dpy, False); -@@ -1498,6 +1508,16 @@ setfullscreen(Client *c, int fullscreen) - } - - void -+setgaps(const Arg *arg) -+{ -+ if ((arg->i == 0) || (selmon->gappx + arg->i < 0)) -+ selmon->gappx = 0; -+ else -+ selmon->gappx += arg->i; -+ arrange(selmon); -+} -+ -+void - setlayout(const Arg *arg) - { - if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) -@@ -1673,26 +1693,37 @@ tagmon(const Arg *arg) - void - tile(Monitor *m) - { -- unsigned int i, n, h, mw, my, ty; -+ unsigned int i, n, h, mw, my, ty, ns; - Client *c; - - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - if (n == 0) - return; -+ if(n == 1){ -+ c = nexttiled(m->clients); -+ resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); -+ return; -+ } - -- if (n > m->nmaster) -+ 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++) -+ ns = m->nmaster > 0 ? 2 : 1; -+ } -+ else{ -+ mw = m->ww - m->gappx; -+ ns = 1; -+ } -+ for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if (i < m->nmaster) { -- h = (m->wh - my) / (MIN(n, m->nmaster) - i); -- resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); -- my += HEIGHT(c); -+ h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx; -+ resize(c, m->wx + m->gappx, m->wy + my, mw - 2*c->bw - m->gappx*(5-ns)/2, h - 2*c->bw, 0); -+ if(my + HEIGHT(c) + m->gappx < m->wh) -+ my += HEIGHT(c) + m->gappx; - } else { -- h = (m->wh - ty) / (n - i); -- resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); -- ty += HEIGHT(c); -+ h = (m->wh - ty) / (n - i) - m->gappx; -+ resize(c, m->wx + mw + m->gappx/ns, m->wy + ty, m->ww - mw - (2*c->bw) - m->gappx*(5-ns)/2, h - 2*c->bw, 0); -+ if(ty + HEIGHT(c) + m->gappx < m->wh) -+ ty += HEIGHT(c) + m->gappx; - } - } diff --git a/my_dwm/patches/dwm-vanitygaps-20200610-f09418b.diff b/my_dwm/patches/dwm-vanitygaps-20200610-f09418b.diff deleted file mode 100644 index c8b13b2..0000000 --- a/my_dwm/patches/dwm-vanitygaps-20200610-f09418b.diff +++ /dev/null @@ -1,262 +0,0 @@ -From c35fd03ec002e1f4476a75203ff9b5cbcc630177 Mon Sep 17 00:00:00 2001 -From: Michel Boaventura -Date: Wed, 10 Jun 2020 10:46:51 -0300 -Subject: [PATCH] Update Vanity Gaps to master - ---- - config.def.h | 21 +++++++ - dwm.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++---- - 2 files changed, 163 insertions(+), 12 deletions(-) - -diff --git a/config.def.h b/config.def.h -index 1c0b587..0927c2d 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -3,6 +3,11 @@ - /* appearance */ - static const unsigned int borderpx = 1; /* border pixel of windows */ - static const unsigned int snap = 32; /* snap pixel */ -+static const unsigned int gappih = 10; /* horiz inner gap between windows */ -+static const unsigned int gappiv = 10; /* vert inner gap between windows */ -+static const unsigned int gappoh = 10; /* horiz outer gap between windows and screen edge */ -+static const unsigned int gappov = 10; /* vert outer gap between windows and screen edge */ -+static const int smartgaps = 0; /* 1 means no outer gap when there is only one window */ - static const int showbar = 1; /* 0 means no bar */ - static const int topbar = 1; /* 0 means bottom bar */ - static const char *fonts[] = { "monospace:size=10" }; -@@ -70,6 +75,22 @@ static Key keys[] = { - { MODKEY, XK_d, incnmaster, {.i = -1 } }, - { MODKEY, XK_h, setmfact, {.f = -0.05} }, - { MODKEY, XK_l, setmfact, {.f = +0.05} }, -+ { MODKEY|Mod4Mask, XK_h, incrgaps, {.i = +1 } }, -+ { MODKEY|Mod4Mask, XK_l, incrgaps, {.i = -1 } }, -+ { MODKEY|Mod4Mask|ShiftMask, XK_h, incrogaps, {.i = +1 } }, -+ { MODKEY|Mod4Mask|ShiftMask, XK_l, incrogaps, {.i = -1 } }, -+ { MODKEY|Mod4Mask|ControlMask, XK_h, incrigaps, {.i = +1 } }, -+ { MODKEY|Mod4Mask|ControlMask, XK_l, incrigaps, {.i = -1 } }, -+ { MODKEY|Mod4Mask, XK_0, togglegaps, {0} }, -+ { MODKEY|Mod4Mask|ShiftMask, XK_0, defaultgaps, {0} }, -+ { MODKEY, XK_y, incrihgaps, {.i = +1 } }, -+ { MODKEY, XK_o, incrihgaps, {.i = -1 } }, -+ { MODKEY|ControlMask, XK_y, incrivgaps, {.i = +1 } }, -+ { MODKEY|ControlMask, XK_o, incrivgaps, {.i = -1 } }, -+ { MODKEY|Mod4Mask, XK_y, incrohgaps, {.i = +1 } }, -+ { MODKEY|Mod4Mask, XK_o, incrohgaps, {.i = -1 } }, -+ { MODKEY|ShiftMask, XK_y, incrovgaps, {.i = +1 } }, -+ { MODKEY|ShiftMask, XK_o, incrovgaps, {.i = -1 } }, - { MODKEY, XK_Return, zoom, {0} }, - { MODKEY, XK_Tab, view, {0} }, - { MODKEY|ShiftMask, XK_c, killclient, {0} }, -diff --git a/dwm.c b/dwm.c -index 9fd0286..50dbbaf 100644 ---- a/dwm.c -+++ b/dwm.c -@@ -119,6 +119,10 @@ struct Monitor { - int by; /* bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ -+ int gappih; /* horizontal gap between windows */ -+ int gappiv; /* vertical gap between windows */ -+ int gappoh; /* horizontal outer gaps */ -+ int gappov; /* vertical outer gaps */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; -@@ -200,6 +204,16 @@ 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 setgaps(int oh, int ov, int ih, int iv); -+static void incrgaps(const Arg *arg); -+static void incrigaps(const Arg *arg); -+static void incrogaps(const Arg *arg); -+static void incrohgaps(const Arg *arg); -+static void incrovgaps(const Arg *arg); -+static void incrihgaps(const Arg *arg); -+static void incrivgaps(const Arg *arg); -+static void togglegaps(const Arg *arg); -+static void defaultgaps(const Arg *arg); - static void setlayout(const Arg *arg); - static void setmfact(const Arg *arg); - static void setup(void); -@@ -241,6 +255,7 @@ static char stext[256]; - static int screen; - static int sw, sh; /* X display screen geometry width, height */ - static int bh, blw = 0; /* bar geometry */ -+static int enablegaps = 1; /* enables gaps, used by togglegaps */ - static int lrpad; /* sum of left and right padding for text */ - static int (*xerrorxlib)(Display *, XErrorEvent *); - static unsigned int numlockmask = 0; -@@ -639,6 +654,10 @@ createmon(void) - m->nmaster = nmaster; - m->showbar = showbar; - m->topbar = topbar; -+ m->gappih = gappih; -+ m->gappiv = gappiv; -+ m->gappoh = gappoh; -+ m->gappov = gappov; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); -@@ -1498,6 +1517,111 @@ setfullscreen(Client *c, int fullscreen) - } - } - -+void -+setgaps(int oh, int ov, int ih, int iv) -+{ -+ if (oh < 0) oh = 0; -+ if (ov < 0) ov = 0; -+ if (ih < 0) ih = 0; -+ if (iv < 0) iv = 0; -+ -+ selmon->gappoh = oh; -+ selmon->gappov = ov; -+ selmon->gappih = ih; -+ selmon->gappiv = iv; -+ arrange(selmon); -+} -+ -+void -+togglegaps(const Arg *arg) -+{ -+ enablegaps = !enablegaps; -+ arrange(selmon); -+} -+ -+void -+defaultgaps(const Arg *arg) -+{ -+ setgaps(gappoh, gappov, gappih, gappiv); -+} -+ -+void -+incrgaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh + arg->i, -+ selmon->gappov + arg->i, -+ selmon->gappih + arg->i, -+ selmon->gappiv + arg->i -+ ); -+} -+ -+void -+incrigaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh, -+ selmon->gappov, -+ selmon->gappih + arg->i, -+ selmon->gappiv + arg->i -+ ); -+} -+ -+void -+incrogaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh + arg->i, -+ selmon->gappov + arg->i, -+ selmon->gappih, -+ selmon->gappiv -+ ); -+} -+ -+void -+incrohgaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh + arg->i, -+ selmon->gappov, -+ selmon->gappih, -+ selmon->gappiv -+ ); -+} -+ -+void -+incrovgaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh, -+ selmon->gappov + arg->i, -+ selmon->gappih, -+ selmon->gappiv -+ ); -+} -+ -+void -+incrihgaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh, -+ selmon->gappov, -+ selmon->gappih + arg->i, -+ selmon->gappiv -+ ); -+} -+ -+void -+incrivgaps(const Arg *arg) -+{ -+ setgaps( -+ selmon->gappoh, -+ selmon->gappov, -+ selmon->gappih, -+ selmon->gappiv + arg->i -+ ); -+} -+ - void - setlayout(const Arg *arg) - { -@@ -1674,28 +1798,34 @@ tagmon(const Arg *arg) - void - tile(Monitor *m) - { -- unsigned int i, n, h, mw, my, ty; -+ unsigned int i, n, h, r, oe = enablegaps, ie = enablegaps, mw, my, ty; - Client *c; - - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - if (n == 0) - return; - -+ if (smartgaps == n) { -+ oe = 0; // outer gaps disabled -+ } -+ - if (n > m->nmaster) -- mw = m->nmaster ? m->ww * m->mfact : 0; -+ mw = m->nmaster ? (m->ww + m->gappiv*ie) * m->mfact : 0; - else -- mw = m->ww; -- for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) -+ mw = m->ww - 2*m->gappov*oe + m->gappiv*ie; -+ for (i = 0, my = ty = m->gappoh*oe, 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); -+ r = MIN(n, m->nmaster) - i; -+ h = (m->wh - my - m->gappoh*oe - m->gappih*ie * (r - 1)) / r; -+ resize(c, m->wx + m->gappov*oe, m->wy + my, mw - (2*c->bw) - m->gappiv*ie, h - (2*c->bw), 0); -+ if (my + HEIGHT(c) + m->gappih*ie < m->wh) -+ my += HEIGHT(c) + m->gappih*ie; - } 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); -+ r = n - i; -+ h = (m->wh - ty - m->gappoh*oe - m->gappih*ie * (r - 1)) / r; -+ resize(c, m->wx + mw + m->gappov*oe, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappov*oe, h - (2*c->bw), 0); -+ if (ty + HEIGHT(c) + m->gappih*ie < m->wh) -+ ty += HEIGHT(c) + m->gappih*ie; - } - } - --- -2.27.0 - diff --git a/my_dwm/transient.c b/my_dwm/transient.c deleted file mode 100644 index 040adb5..0000000 --- a/my_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/my_dwm/util.c b/my_dwm/util.c deleted file mode 100644 index fe044fc..0000000 --- a/my_dwm/util.c +++ /dev/null @@ -1,35 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include -#include -#include -#include - -#include "util.h" - -void * -ecalloc(size_t nmemb, size_t size) -{ - void *p; - - if (!(p = calloc(nmemb, size))) - die("calloc:"); - return p; -} - -void -die(const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - - if (fmt[0] && fmt[strlen(fmt)-1] == ':') { - fputc(' ', stderr); - perror(NULL); - } else { - fputc('\n', stderr); - } - - exit(1); -} diff --git a/my_dwm/util.h b/my_dwm/util.h deleted file mode 100644 index f633b51..0000000 --- a/my_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/packages.txt b/packages.txt deleted file mode 100644 index 8035c82..0000000 --- a/packages.txt +++ /dev/null @@ -1 +0,0 @@ -yay -S xorg-xbacklight diff --git a/problems.md b/problems.md deleted file mode 100644 index 1160d5d..0000000 --- a/problems.md +++ /dev/null @@ -1,6 +0,0 @@ -# List of often problems and their solutions - -### `gpg: keyserver receive failed: General error` -``` bash -gpg --keyserver keys.gnupg.net --recv-keys CB9387521E1EE0127DA804843FDBB55084CC5D84 -``` diff --git a/st/FAQ b/st/FAQ deleted file mode 100644 index 0f9609d..0000000 --- a/st/FAQ +++ /dev/null @@ -1,250 +0,0 @@ -## Why does st not handle utmp entries? - -Use the excellent tool of [utmp](https://git.suckless.org/utmp/) for this task. - - -## Some _random program_ complains that st is unknown/not recognised/unsupported/whatever! - -It means that st doesn’t have any terminfo entry on your system. Chances are -you did not `make install`. If you just want to test it without installing it, -you can manually run `tic -sx st.info`. - - -## Nothing works, and nothing is said about an unknown terminal! - -* Some programs just assume they’re running in xterm i.e. they don’t rely on - terminfo. What you see is the current state of the “xterm compliance”. -* Some programs don’t complain about the lacking st description and default to - another terminal. In that case see the question about terminfo. - - -## How do I scroll back up? - -* Using a terminal multiplexer. - * `st -e tmux` using C-b [ - * `st -e screen` using C-a ESC -* Using the excellent tool of [scroll](https://git.suckless.org/scroll/). -* Using the scrollback [patch](https://st.suckless.org/patches/scrollback/). - - -## I would like to have utmp and/or scroll functionality by default - -You can add the absolute patch of both programs in your config.h -file. You only have to modify the value of utmp and scroll variables. - - -## Why doesn't the Del key work in some programs? - -Taken from the terminfo manpage: - - If the terminal has a keypad that transmits codes when the keys - are pressed, this information can be given. Note that it is not - possible to handle terminals where the keypad only works in - local (this applies, for example, to the unshifted HP 2621 keys). - If the keypad can be set to transmit or not transmit, give these - codes as smkx and rmkx. Otherwise the keypad is assumed to - always transmit. - -In the st case smkx=E[?1hE= and rmkx=E[?1lE>, so it is mandatory that -applications which want to test against keypad keys send these -sequences. - -But buggy applications (like bash and irssi, for example) don't do this. A fast -solution for them is to use the following command: - - $ printf '\033[?1h\033=' >/dev/tty - -or - $ tput smkx - -In the case of bash, readline is used. Readline has a different note in its -manpage about this issue: - - enable-keypad (Off) - When set to On, readline will try to enable the - application keypad when it is called. Some systems - need this to enable arrow keys. - -Adding this option to your .inputrc will fix the keypad problem for all -applications using readline. - -If you are using zsh, then read the zsh FAQ -: - - It should be noted that the O / [ confusion can occur with other keys - such as Home and End. Some systems let you query the key sequences - sent by these keys from the system's terminal database, terminfo. - Unfortunately, the key sequences given there typically apply to the - mode that is not the one zsh uses by default (it's the "application" - mode rather than the "raw" mode). Explaining the use of terminfo is - outside of the scope of this FAQ, but if you wish to use the key - sequences given there you can tell the line editor to turn on - "application" mode when it starts and turn it off when it stops: - - function zle-line-init () { echoti smkx } - function zle-line-finish () { echoti rmkx } - zle -N zle-line-init - zle -N zle-line-finish - -Putting these lines into your .zshrc will fix the problems. - - -## How can I use meta in 8bit mode? - -St supports meta in 8bit mode, but the default terminfo entry doesn't -use this capability. If you want it, you have to use the 'st-meta' value -in TERM. - - -## I cannot compile st in OpenBSD - -OpenBSD lacks librt, despite it being mandatory in POSIX -. -If you want to compile st for OpenBSD you have to remove -lrt from config.mk, and -st will compile without any loss of functionality, because all the functions are -included in libc on this platform. - - -## The Backspace Case - -St is emulating the Linux way of handling backspace being delete and delete being -backspace. - -This is an issue that was discussed in suckless mailing list -. Here is why some old grumpy -terminal users wants its backspace to be how he feels it: - - Well, I am going to comment why I want to change the behaviour - of this key. When ASCII was defined in 1968, communication - with computers was done using punched cards, or hardcopy - terminals (basically a typewriter machine connected with the - computer using a serial port). ASCII defines DELETE as 7F, - because, in punched-card terms, it means all the holes of the - card punched; it is thus a kind of 'physical delete'. In the - same way, the BACKSPACE key was a non-destructive backspace, - as on a typewriter. So, if you wanted to delete a character, - you had to BACKSPACE and then DELETE. Another use of BACKSPACE - was to type accented characters, for example 'a BACKSPACE `'. - The VT100 had no BACKSPACE key; it was generated using the - CONTROL key as another control character (CONTROL key sets to - 0 b7 b6 b5, so it converts H (code 0x48) into BACKSPACE (code - 0x08)), but it had a DELETE key in a similar position where - the BACKSPACE key is located today on common PC keyboards. - All the terminal emulators emulated the difference between - these keys correctly: the backspace key generated a BACKSPACE - (^H) and delete key generated a DELETE (^?). - - But a problem arose when Linus Torvalds wrote Linux. Unlike - earlier terminals, the Linux virtual terminal (the terminal - emulator integrated in the kernel) returned a DELETE when - backspace was pressed, due to the VT100 having a DELETE key in - the same position. This created a lot of problems (see [1] - and [2]). Since Linux has become the king, a lot of terminal - emulators today generate a DELETE when the backspace key is - pressed in order to avoid problems with Linux. The result is - that the only way of generating a BACKSPACE on these systems - is by using CONTROL + H. (I also think that emacs had an - important point here because the CONTROL + H prefix is used - in emacs in some commands (help commands).) - - From point of view of the kernel, you can change the key - for deleting a previous character with stty erase. When you - connect a real terminal into a machine you describe the type - of terminal, so getty configures the correct value of stty - erase for this terminal. In the case of terminal emulators, - however, you don't have any getty that can set the correct - value of stty erase, so you always get the default value. - For this reason, it is necessary to add 'stty erase ^H' to your - profile if you have changed the value of the backspace key. - Of course, another solution is for st itself to modify the - value of stty erase. I usually have the inverse problem: - when I connect to non-Unix machines, I have to press CONTROL + - h to get a BACKSPACE. The inverse problem occurs when a user - connects to my Unix machines from a different system with a - correct backspace key. - - [1] http://www.ibb.net/~anne/keyboard.html - [2] http://www.tldp.org/HOWTO/Keyboard-and-Console-HOWTO-5.html - - -## But I really want the old grumpy behaviour of my terminal - -Apply [1]. - -[1] https://st.suckless.org/patches/delkey - - -## Why do images not work in st using the w3m image hack? - -w3mimg uses a hack that draws an image on top of the terminal emulator Drawable -window. The hack relies on the terminal to use a single buffer to draw its -contents directly. - -st uses double-buffered drawing so the image is quickly replaced and may show a -short flicker effect. - -Below is a patch example to change st double-buffering to a single Drawable -buffer. - -diff --git a/x.c b/x.c ---- a/x.c -+++ b/x.c -@@ -732,10 +732,6 @@ xresize(int col, int row) - win.tw = col * win.cw; - win.th = row * win.ch; - -- XFreePixmap(xw.dpy, xw.buf); -- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, -- DefaultDepth(xw.dpy, xw.scr)); -- XftDrawChange(xw.draw, xw.buf); - xclear(0, 0, win.w, win.h); - - /* resize to new width */ -@@ -1148,8 +1144,7 @@ xinit(int cols, int rows) - gcvalues.graphics_exposures = False; - dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, - &gcvalues); -- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, -- DefaultDepth(xw.dpy, xw.scr)); -+ xw.buf = xw.win; - XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); - XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); - -@@ -1632,8 +1627,6 @@ xdrawline(Line line, int x1, int y1, int x2) - void - xfinishdraw(void) - { -- XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, -- win.h, 0, 0); - XSetForeground(xw.dpy, dc.gc, - dc.col[IS_SET(MODE_REVERSE)? - defaultfg : defaultbg].pixel); - - -## BadLength X error in Xft when trying to render emoji - -Xft makes st crash when rendering color emojis with the following error: - -"X Error of failed request: BadLength (poly request too large or internal Xlib length error)" - Major opcode of failed request: 139 (RENDER) - Minor opcode of failed request: 20 (RenderAddGlyphs) - Serial number of failed request: 1595 - Current serial number in output stream: 1818" - -This is a known bug in Xft (not st) which happens on some platforms and -combination of particular fonts and fontconfig settings. - -See also: -https://gitlab.freedesktop.org/xorg/lib/libxft/issues/6 -https://bugs.freedesktop.org/show_bug.cgi?id=107534 -https://bugzilla.redhat.com/show_bug.cgi?id=1498269 - -The solution is to remove color emoji fonts or disable this in the fontconfig -XML configuration. As an ugly workaround (which may work only on newer -fontconfig versions (FC_COLOR)), the following code can be used to mask color -fonts: - - FcPatternAddBool(fcpattern, FC_COLOR, FcFalse); - -Please don't bother reporting this bug to st, but notify the upstream Xft -developers about fixing this bug. diff --git a/st/LEGACY b/st/LEGACY deleted file mode 100644 index bf28b1e..0000000 --- a/st/LEGACY +++ /dev/null @@ -1,17 +0,0 @@ -A STATEMENT ON LEGACY SUPPORT - -In the terminal world there is much cruft that comes from old and unsup‐ -ported terminals that inherit incompatible modes and escape sequences -which noone is able to know, except when he/she comes from that time and -developed a graphical vt100 emulator at that time. - -One goal of st is to only support what is really needed. When you en‐ -counter a sequence which you really need, implement it. But while you -are at it, do not add the other cruft you might encounter while sneek‐ -ing at other terminal emulators. History has bloated them and there is -no real evidence that most of the sequences are used today. - - -Christoph Lohmann <20h@r-36.net> -2012-09-13T07:00:36.081271045+02:00 - diff --git a/st/LICENSE b/st/LICENSE deleted file mode 100644 index d80eb47..0000000 --- a/st/LICENSE +++ /dev/null @@ -1,34 +0,0 @@ -MIT/X Consortium License - -© 2014-2020 Hiltjo Posthuma -© 2018 Devin J. Pohly -© 2014-2017 Quentin Rameau -© 2009-2012 Aurélien APTEL -© 2008-2017 Anselm R Garbe -© 2012-2017 Roberto E. Vargas Caballero -© 2012-2016 Christoph Lohmann <20h at r-36 dot net> -© 2013 Eon S. Jeon -© 2013 Alexander Sedov -© 2013 Mark Edgar -© 2013-2014 Eric Pruitt -© 2013 Michael Forney -© 2013-2014 Markus Teich -© 2014-2015 Laslo Hunhold - -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/st/Makefile b/st/Makefile deleted file mode 100644 index 470ac86..0000000 --- a/st/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -# st - simple terminal -# See LICENSE file for copyright and license details. -.POSIX: - -include config.mk - -SRC = st.c x.c -OBJ = $(SRC:.c=.o) - -all: options st - -options: - @echo st build options: - @echo "CFLAGS = $(STCFLAGS)" - @echo "LDFLAGS = $(STLDFLAGS)" - @echo "CC = $(CC)" - -config.h: - cp config.def.h config.h - -.c.o: - $(CC) $(STCFLAGS) -c $< - -st.o: config.h st.h win.h -x.o: arg.h config.h st.h win.h - -$(OBJ): config.h config.mk - -st: $(OBJ) - $(CC) -o $@ $(OBJ) $(STLDFLAGS) - -clean: - rm -f st $(OBJ) st-$(VERSION).tar.gz - -dist: clean - mkdir -p st-$(VERSION) - cp -R FAQ LEGACY TODO LICENSE Makefile README config.mk\ - config.def.h st.info st.1 arg.h st.h win.h $(SRC)\ - st-$(VERSION) - tar -cf - st-$(VERSION) | gzip > st-$(VERSION).tar.gz - rm -rf st-$(VERSION) - -install: st - mkdir -p $(DESTDIR)$(PREFIX)/bin - cp -f st $(DESTDIR)$(PREFIX)/bin - chmod 755 $(DESTDIR)$(PREFIX)/bin/st - mkdir -p $(DESTDIR)$(MANPREFIX)/man1 - sed "s/VERSION/$(VERSION)/g" < st.1 > $(DESTDIR)$(MANPREFIX)/man1/st.1 - chmod 644 $(DESTDIR)$(MANPREFIX)/man1/st.1 - tic -sx st.info - @echo Please see the README file regarding the terminfo entry of st. - -uninstall: - rm -f $(DESTDIR)$(PREFIX)/bin/st - rm -f $(DESTDIR)$(MANPREFIX)/man1/st.1 - -.PHONY: all options clean dist install uninstall diff --git a/st/README b/st/README deleted file mode 100644 index 6a846ed..0000000 --- a/st/README +++ /dev/null @@ -1,34 +0,0 @@ -st - simple terminal --------------------- -st is a simple terminal emulator for X which sucks less. - - -Requirements ------------- -In order to build st you need the Xlib header files. - - -Installation ------------- -Edit config.mk to match your local setup (st is installed into -the /usr/local namespace by default). - -Afterwards enter the following command to build and install st (if -necessary as root): - - make clean install - - -Running st ----------- -If you did not install st with make clean install, you must compile -the st terminfo entry with the following command: - - tic -sx st.info - -See the man page for additional details. - -Credits -------- -Based on Aurélien APTEL bt source code. - diff --git a/st/TODO b/st/TODO deleted file mode 100644 index 5f74cd5..0000000 --- a/st/TODO +++ /dev/null @@ -1,28 +0,0 @@ -vt emulation ------------- - -* double-height support - -code & interface ----------------- - -* add a simple way to do multiplexing - -drawing -------- -* add diacritics support to xdraws() - * switch to a suckless font drawing library -* make the font cache simpler -* add better support for brightening of the upper colors - -bugs ----- - -* fix shift up/down (shift selection in emacs) -* remove DEC test sequence when appropriate - -misc ----- - - $ grep -nE 'XXX|TODO' st.c - diff --git a/st/arg.h b/st/arg.h deleted file mode 100644 index a22e019..0000000 --- a/st/arg.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copy me if you can. - * by 20h - */ - -#ifndef ARG_H__ -#define ARG_H__ - -extern char *argv0; - -/* use main(int argc, char *argv[]) */ -#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ - argv[0] && argv[0][0] == '-'\ - && argv[0][1];\ - argc--, argv++) {\ - char argc_;\ - char **argv_;\ - int brk_;\ - if (argv[0][1] == '-' && argv[0][2] == '\0') {\ - argv++;\ - argc--;\ - break;\ - }\ - int i_;\ - for (i_ = 1, brk_ = 0, argv_ = argv;\ - argv[0][i_] && !brk_;\ - i_++) {\ - if (argv_ != argv)\ - break;\ - argc_ = argv[0][i_];\ - switch (argc_) - -#define ARGEND }\ - } - -#define ARGC() argc_ - -#define EARGF(x) ((argv[0][i_+1] == '\0' && argv[1] == NULL)?\ - ((x), abort(), (char *)0) :\ - (brk_ = 1, (argv[0][i_+1] != '\0')?\ - (&argv[0][i_+1]) :\ - (argc--, argv++, argv[0]))) - -#define ARGF() ((argv[0][i_+1] == '\0' && argv[1] == NULL)?\ - (char *)0 :\ - (brk_ = 1, (argv[0][i_+1] != '\0')?\ - (&argv[0][i_+1]) :\ - (argc--, argv++, argv[0]))) - -#endif diff --git a/st/config.def.h b/st/config.def.h deleted file mode 100644 index 3982f24..0000000 --- a/st/config.def.h +++ /dev/null @@ -1,468 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* - * appearance - * - * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html - */ -static char *font = "Mononoki:pixelsize=16:antialias=true:autohint=true"; -static char *font2 = "Joypixels:pixelsize=16:antialias=true:autohint=true"; - -static int borderpx = 2; - -/* - * What program is execed by st depends of these precedence rules: - * 1: program passed with -e - * 2: scroll and/or utmp - * 3: SHELL environment variable - * 4: value of shell in /etc/passwd - * 5: value of shell in config.h - */ -static char *shell = "/bin/sh"; -char *utmp = NULL; -/* scroll program: to enable use a string like "scroll" */ -char *scroll = NULL; -char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400"; - -/* identification sequence returned in DA and DECID */ -char *vtiden = "\033[?6c"; - -/* Kerning / character bounding-box multipliers */ -static float cwscale = 1.0; -static float chscale = 1.0; - -/* - * word delimiter string - * - * More advanced example: L" `'\"()[]{}" - */ -wchar_t *worddelimiters = L" "; - -/* selection timeouts (in milliseconds) */ -static unsigned int doubleclicktimeout = 300; -static unsigned int tripleclicktimeout = 600; - -/* alt screens */ -int allowaltscreen = 1; - -/* allow certain non-interactive (insecure) window operations such as: - setting the clipboard text */ -int allowwindowops = 0; - -/* - * draw latency range in ms - from new content/keypress/etc until drawing. - * within this range, st draws when content stops arriving (idle). mostly it's - * near minlatency, but it waits longer for slow updates to avoid partial draw. - * low minlatency will tear/flicker more, as it can "detect" idle too early. - */ -static double minlatency = 8; -static double maxlatency = 33; - -/* - * blinking timeout (set to 0 to disable blinking) for the terminal blinking - * attribute. - */ -static unsigned int blinktimeout = 800; - -/* - * thickness of underline and bar cursors - */ -static unsigned int cursorthickness = 2; - -/* - * bell volume. It must be a value between -100 and 100. Use 0 for disabling - * it - */ -static int bellvolume = 0; - -/* default TERM value */ -char *termname = "st-256color"; - -/* - * spaces per tab - * - * When you are changing this value, don't forget to adapt the »it« value in - * the st.info and appropriately install the st.info in the environment where - * you use this st version. - * - * it#$tabspaces, - * - * Secondly make sure your kernel is not expanding tabs. When running `stty - * -a` »tab0« should appear. You can tell the terminal to not expand tabs by - * running following command: - * - * stty tabs - */ -unsigned int tabspaces = 8; - -/* Terminal colors (16 first used in escape sequence) */ -static const char *colorname[] = { - - /* 8 normal colors */ - [0] = "#282828", /* hard contrast: #1d2021 / soft contrast: #32302f */ - [1] = "#cc241d", /* red */ - [2] = "#98971a", /* green */ - [3] = "#d79921", /* yellow */ - [4] = "#458588", /* blue */ - [5] = "#b16286", /* magenta */ - [6] = "#689d6a", /* cyan */ - [7] = "#a89984", /* white */ - - /* 8 bright colors */ - [8] = "#928374", /* black */ - [9] = "#fb4934", /* red */ - [10] = "#b8bb26", /* green */ - [11] = "#fabd2f", /* yellow */ - [12] = "#83a598", /* blue */ - [13] = "#d3869b", /* magenta */ - [14] = "#8ec07c", /* cyan */ - [15] = "#ebdbb2", /* white */ -}; - -/* - * Default colors (colorname index) - * foreground, background, cursor - */ -unsigned int defaultfg = 15; -unsigned int defaultbg = 0; -static unsigned int defaultcs = 15; -static unsigned int defaultrcs = 257; - -/* - * Default shape of cursor - * 2: Block ("█") - * 4: Underline ("_") - * 6: Bar ("|") - * 7: Snowman ("☃") - */ -static unsigned int cursorshape = 2; - -/* - * Default columns and rows numbers - */ - -static unsigned int cols = 80; -static unsigned int rows = 24; - -/* - * Default colour and shape of the mouse cursor - */ -static unsigned int mouseshape = XC_xterm; -static unsigned int mousefg = 7; -static unsigned int mousebg = 0; - -/* - * Color used to display font attributes when fontconfig selected a font which - * doesn't match the ones requested. - */ -static unsigned int defaultattr = 11; - -/* - * Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set). - * Note that if you want to use ShiftMask with selmasks, set this to an other - * modifier, set to 0 to not use it. - */ -static uint forcemousemod = ShiftMask; - -/* - * Internal mouse shortcuts. - * Beware that overloading Button1 will disable the selection. - */ -static MouseShortcut mshortcuts[] = { - /* mask button function argument release */ - { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 }, - { ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} }, - { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} }, - { ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} }, - { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} }, -}; - -/* Internal keyboard shortcuts. */ -#define MODKEY Mod1Mask -#define TERMMOD (ControlMask|ShiftMask) - -static Shortcut shortcuts[] = { - /* mask keysym function argument */ - { XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} }, - { ControlMask, XK_Print, toggleprinter, {.i = 0} }, - { ShiftMask, XK_Print, printscreen, {.i = 0} }, - { XK_ANY_MOD, XK_Print, printsel, {.i = 0} }, - { TERMMOD, XK_Prior, zoom, {.f = +1} }, - { TERMMOD, XK_Next, zoom, {.f = -1} }, - { TERMMOD, XK_Home, zoomreset, {.f = 0} }, - { TERMMOD, XK_C, clipcopy, {.i = 0} }, - { TERMMOD, XK_V, clippaste, {.i = 0} }, - { TERMMOD, XK_Y, selpaste, {.i = 0} }, - { ShiftMask, XK_Insert, selpaste, {.i = 0} }, - { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, -}; - -/* - * Special keys (change & recompile st.info accordingly) - * - * Mask value: - * * Use XK_ANY_MOD to match the key no matter modifiers state - * * Use XK_NO_MOD to match the key alone (no modifiers) - * appkey value: - * * 0: no value - * * > 0: keypad application mode enabled - * * = 2: term.numlock = 1 - * * < 0: keypad application mode disabled - * appcursor value: - * * 0: no value - * * > 0: cursor application mode enabled - * * < 0: cursor application mode disabled - * - * Be careful with the order of the definitions because st searches in - * this table sequentially, so any XK_ANY_MOD must be in the last - * position for a key. - */ - -/* - * If you want keys other than the X11 function keys (0xFD00 - 0xFFFF) - * to be mapped below, add them to this array. - */ -static KeySym mappedkeys[] = { -1 }; - -/* - * State bits to ignore when matching key or button events. By default, - * numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored. - */ -static uint ignoremod = Mod2Mask|XK_SWITCH_MOD; - -/* - * This is the huge key array which defines all compatibility to the Linux - * world. Please decide about changes wisely. - */ -static Key key[] = { - /* keysym mask string appkey appcursor */ - { XK_KP_Home, ShiftMask, "\033[2J", 0, -1}, - { XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1}, - { XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1}, - { XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1}, - { XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0}, - { XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1}, - { XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1}, - { XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0}, - { XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1}, - { XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1}, - { XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0}, - { XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1}, - { XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1}, - { XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0}, - { XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1}, - { XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1}, - { XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0}, - { XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, - { XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0}, - { XK_KP_End, ControlMask, "\033[J", -1, 0}, - { XK_KP_End, ControlMask, "\033[1;5F", +1, 0}, - { XK_KP_End, ShiftMask, "\033[K", -1, 0}, - { XK_KP_End, ShiftMask, "\033[1;2F", +1, 0}, - { XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0}, - { XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0}, - { XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0}, - { XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0}, - { XK_KP_Insert, ShiftMask, "\033[4l", -1, 0}, - { XK_KP_Insert, ControlMask, "\033[L", -1, 0}, - { XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0}, - { XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, - { XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, - { XK_KP_Delete, ControlMask, "\033[M", -1, 0}, - { XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0}, - { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0}, - { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0}, - { XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0}, - { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, - { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0}, - { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0}, - { XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0}, - { XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0}, - { XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0}, - { XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0}, - { XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0}, - { XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0}, - { XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0}, - { XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0}, - { XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0}, - { XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0}, - { XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0}, - { XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0}, - { XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0}, - { XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0}, - { XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0}, - { XK_Up, ShiftMask, "\033[1;2A", 0, 0}, - { XK_Up, Mod1Mask, "\033[1;3A", 0, 0}, - { XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0}, - { XK_Up, ControlMask, "\033[1;5A", 0, 0}, - { XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0}, - { XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0}, - { XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0}, - { XK_Up, XK_ANY_MOD, "\033[A", 0, -1}, - { XK_Up, XK_ANY_MOD, "\033OA", 0, +1}, - { XK_Down, ShiftMask, "\033[1;2B", 0, 0}, - { XK_Down, Mod1Mask, "\033[1;3B", 0, 0}, - { XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0}, - { XK_Down, ControlMask, "\033[1;5B", 0, 0}, - { XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0}, - { XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0}, - { XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0}, - { XK_Down, XK_ANY_MOD, "\033[B", 0, -1}, - { XK_Down, XK_ANY_MOD, "\033OB", 0, +1}, - { XK_Left, ShiftMask, "\033[1;2D", 0, 0}, - { XK_Left, Mod1Mask, "\033[1;3D", 0, 0}, - { XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0}, - { XK_Left, ControlMask, "\033[1;5D", 0, 0}, - { XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0}, - { XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0}, - { XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0}, - { XK_Left, XK_ANY_MOD, "\033[D", 0, -1}, - { XK_Left, XK_ANY_MOD, "\033OD", 0, +1}, - { XK_Right, ShiftMask, "\033[1;2C", 0, 0}, - { XK_Right, Mod1Mask, "\033[1;3C", 0, 0}, - { XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0}, - { XK_Right, ControlMask, "\033[1;5C", 0, 0}, - { XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0}, - { XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0}, - { XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0}, - { XK_Right, XK_ANY_MOD, "\033[C", 0, -1}, - { XK_Right, XK_ANY_MOD, "\033OC", 0, +1}, - { XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0}, - { XK_Return, Mod1Mask, "\033\r", 0, 0}, - { XK_Return, XK_ANY_MOD, "\r", 0, 0}, - { XK_Insert, ShiftMask, "\033[4l", -1, 0}, - { XK_Insert, ShiftMask, "\033[2;2~", +1, 0}, - { XK_Insert, ControlMask, "\033[L", -1, 0}, - { XK_Insert, ControlMask, "\033[2;5~", +1, 0}, - { XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, - { XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, - { XK_Delete, ControlMask, "\033[M", -1, 0}, - { XK_Delete, ControlMask, "\033[3;5~", +1, 0}, - { XK_Delete, ShiftMask, "\033[2K", -1, 0}, - { XK_Delete, ShiftMask, "\033[3;2~", +1, 0}, - { XK_Delete, XK_ANY_MOD, "\033[P", -1, 0}, - { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, - { XK_BackSpace, XK_NO_MOD, "\177", 0, 0}, - { XK_BackSpace, Mod1Mask, "\033\177", 0, 0}, - { XK_Home, ShiftMask, "\033[2J", 0, -1}, - { XK_Home, ShiftMask, "\033[1;2H", 0, +1}, - { XK_Home, XK_ANY_MOD, "\033[H", 0, -1}, - { XK_Home, XK_ANY_MOD, "\033[1~", 0, +1}, - { XK_End, ControlMask, "\033[J", -1, 0}, - { XK_End, ControlMask, "\033[1;5F", +1, 0}, - { XK_End, ShiftMask, "\033[K", -1, 0}, - { XK_End, ShiftMask, "\033[1;2F", +1, 0}, - { XK_End, XK_ANY_MOD, "\033[4~", 0, 0}, - { XK_Prior, ControlMask, "\033[5;5~", 0, 0}, - { XK_Prior, ShiftMask, "\033[5;2~", 0, 0}, - { XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, - { XK_Next, ControlMask, "\033[6;5~", 0, 0}, - { XK_Next, ShiftMask, "\033[6;2~", 0, 0}, - { XK_Next, XK_ANY_MOD, "\033[6~", 0, 0}, - { XK_F1, XK_NO_MOD, "\033OP" , 0, 0}, - { XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0}, - { XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0}, - { XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0}, - { XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0}, - { XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0}, - { XK_F2, XK_NO_MOD, "\033OQ" , 0, 0}, - { XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0}, - { XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0}, - { XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0}, - { XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0}, - { XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0}, - { XK_F3, XK_NO_MOD, "\033OR" , 0, 0}, - { XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0}, - { XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0}, - { XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0}, - { XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0}, - { XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0}, - { XK_F4, XK_NO_MOD, "\033OS" , 0, 0}, - { XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0}, - { XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0}, - { XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0}, - { XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0}, - { XK_F5, XK_NO_MOD, "\033[15~", 0, 0}, - { XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0}, - { XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0}, - { XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0}, - { XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0}, - { XK_F6, XK_NO_MOD, "\033[17~", 0, 0}, - { XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0}, - { XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0}, - { XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0}, - { XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0}, - { XK_F7, XK_NO_MOD, "\033[18~", 0, 0}, - { XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0}, - { XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0}, - { XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0}, - { XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0}, - { XK_F8, XK_NO_MOD, "\033[19~", 0, 0}, - { XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0}, - { XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0}, - { XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0}, - { XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0}, - { XK_F9, XK_NO_MOD, "\033[20~", 0, 0}, - { XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0}, - { XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0}, - { XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0}, - { XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0}, - { XK_F10, XK_NO_MOD, "\033[21~", 0, 0}, - { XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0}, - { XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0}, - { XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0}, - { XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0}, - { XK_F11, XK_NO_MOD, "\033[23~", 0, 0}, - { XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0}, - { XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0}, - { XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0}, - { XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0}, - { XK_F12, XK_NO_MOD, "\033[24~", 0, 0}, - { XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0}, - { XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0}, - { XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0}, - { XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0}, - { XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0}, - { XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0}, - { XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0}, - { XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0}, - { XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0}, - { XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0}, - { XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0}, - { XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0}, - { XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0}, - { XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0}, - { XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0}, - { XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0}, - { XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0}, - { XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0}, - { XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0}, - { XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0}, - { XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0}, - { XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0}, - { XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0}, - { XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0}, - { XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0}, - { XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0}, - { XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0}, -}; - -/* - * Selection types' masks. - * Use the same masks as usual. - * Button1Mask is always unset, to make masks match between ButtonPress. - * ButtonRelease and MotionNotify. - * If no match is found, regular selection is used. - */ -static uint selmasks[] = { - [SEL_RECTANGULAR] = Mod1Mask, -}; - -/* - * Printable characters in ASCII, used to estimate the advance width - * of single wide characters. - */ -static char ascii_printable[] = - " !\"#$%&'()*+,-./0123456789:;<=>?" - "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" - "`abcdefghijklmnopqrstuvwxyz{|}~"; diff --git a/st/config.def.h.orig b/st/config.def.h.orig deleted file mode 100644 index 4c46c78..0000000 --- a/st/config.def.h.orig +++ /dev/null @@ -1,466 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* - * appearance - * - * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html - */ -static char *font = "Mononoki:pixelsize=16:antialias=true:autohint=true,EmojiOne"; -static int borderpx = 2; - -/* - * What program is execed by st depends of these precedence rules: - * 1: program passed with -e - * 2: scroll and/or utmp - * 3: SHELL environment variable - * 4: value of shell in /etc/passwd - * 5: value of shell in config.h - */ -static char *shell = "/bin/sh"; -char *utmp = NULL; -/* scroll program: to enable use a string like "scroll" */ -char *scroll = NULL; -char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400"; - -/* identification sequence returned in DA and DECID */ -char *vtiden = "\033[?6c"; - -/* Kerning / character bounding-box multipliers */ -static float cwscale = 1.0; -static float chscale = 1.0; - -/* - * word delimiter string - * - * More advanced example: L" `'\"()[]{}" - */ -wchar_t *worddelimiters = L" "; - -/* selection timeouts (in milliseconds) */ -static unsigned int doubleclicktimeout = 300; -static unsigned int tripleclicktimeout = 600; - -/* alt screens */ -int allowaltscreen = 1; - -/* allow certain non-interactive (insecure) window operations such as: - setting the clipboard text */ -int allowwindowops = 0; - -/* - * draw latency range in ms - from new content/keypress/etc until drawing. - * within this range, st draws when content stops arriving (idle). mostly it's - * near minlatency, but it waits longer for slow updates to avoid partial draw. - * low minlatency will tear/flicker more, as it can "detect" idle too early. - */ -static double minlatency = 8; -static double maxlatency = 33; - -/* - * blinking timeout (set to 0 to disable blinking) for the terminal blinking - * attribute. - */ -static unsigned int blinktimeout = 800; - -/* - * thickness of underline and bar cursors - */ -static unsigned int cursorthickness = 2; - -/* - * bell volume. It must be a value between -100 and 100. Use 0 for disabling - * it - */ -static int bellvolume = 0; - -/* default TERM value */ -char *termname = "st-256color"; - -/* - * spaces per tab - * - * When you are changing this value, don't forget to adapt the »it« value in - * the st.info and appropriately install the st.info in the environment where - * you use this st version. - * - * it#$tabspaces, - * - * Secondly make sure your kernel is not expanding tabs. When running `stty - * -a` »tab0« should appear. You can tell the terminal to not expand tabs by - * running following command: - * - * stty tabs - */ -unsigned int tabspaces = 8; - -/* Terminal colors (16 first used in escape sequence) */ -static const char *colorname[] = { - - /* 8 normal colors */ - [0] = "#282828", /* hard contrast: #1d2021 / soft contrast: #32302f */ - [1] = "#cc241d", /* red */ - [2] = "#98971a", /* green */ - [3] = "#d79921", /* yellow */ - [4] = "#458588", /* blue */ - [5] = "#b16286", /* magenta */ - [6] = "#689d6a", /* cyan */ - [7] = "#a89984", /* white */ - - /* 8 bright colors */ - [8] = "#928374", /* black */ - [9] = "#fb4934", /* red */ - [10] = "#b8bb26", /* green */ - [11] = "#fabd2f", /* yellow */ - [12] = "#83a598", /* blue */ - [13] = "#d3869b", /* magenta */ - [14] = "#8ec07c", /* cyan */ - [15] = "#ebdbb2", /* white */ -}; - -/* - * Default colors (colorname index) - * foreground, background, cursor - */ -unsigned int defaultfg = 15; -unsigned int defaultbg = 0; -static unsigned int defaultcs = 15; -static unsigned int defaultrcs = 257; - -/* - * Default shape of cursor - * 2: Block ("█") - * 4: Underline ("_") - * 6: Bar ("|") - * 7: Snowman ("☃") - */ -static unsigned int cursorshape = 2; - -/* - * Default columns and rows numbers - */ - -static unsigned int cols = 80; -static unsigned int rows = 24; - -/* - * Default colour and shape of the mouse cursor - */ -static unsigned int mouseshape = XC_xterm; -static unsigned int mousefg = 7; -static unsigned int mousebg = 0; - -/* - * Color used to display font attributes when fontconfig selected a font which - * doesn't match the ones requested. - */ -static unsigned int defaultattr = 11; - -/* - * Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set). - * Note that if you want to use ShiftMask with selmasks, set this to an other - * modifier, set to 0 to not use it. - */ -static uint forcemousemod = ShiftMask; - -/* - * Internal mouse shortcuts. - * Beware that overloading Button1 will disable the selection. - */ -static MouseShortcut mshortcuts[] = { - /* mask button function argument release */ - { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 }, - { ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} }, - { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} }, - { ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} }, - { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} }, -}; - -/* Internal keyboard shortcuts. */ -#define MODKEY Mod1Mask -#define TERMMOD (ControlMask|ShiftMask) - -static Shortcut shortcuts[] = { - /* mask keysym function argument */ - { XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} }, - { ControlMask, XK_Print, toggleprinter, {.i = 0} }, - { ShiftMask, XK_Print, printscreen, {.i = 0} }, - { XK_ANY_MOD, XK_Print, printsel, {.i = 0} }, - { TERMMOD, XK_Prior, zoom, {.f = +1} }, - { TERMMOD, XK_Next, zoom, {.f = -1} }, - { TERMMOD, XK_Home, zoomreset, {.f = 0} }, - { TERMMOD, XK_C, clipcopy, {.i = 0} }, - { TERMMOD, XK_V, clippaste, {.i = 0} }, - { TERMMOD, XK_Y, selpaste, {.i = 0} }, - { ShiftMask, XK_Insert, selpaste, {.i = 0} }, - { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, -}; - -/* - * Special keys (change & recompile st.info accordingly) - * - * Mask value: - * * Use XK_ANY_MOD to match the key no matter modifiers state - * * Use XK_NO_MOD to match the key alone (no modifiers) - * appkey value: - * * 0: no value - * * > 0: keypad application mode enabled - * * = 2: term.numlock = 1 - * * < 0: keypad application mode disabled - * appcursor value: - * * 0: no value - * * > 0: cursor application mode enabled - * * < 0: cursor application mode disabled - * - * Be careful with the order of the definitions because st searches in - * this table sequentially, so any XK_ANY_MOD must be in the last - * position for a key. - */ - -/* - * If you want keys other than the X11 function keys (0xFD00 - 0xFFFF) - * to be mapped below, add them to this array. - */ -static KeySym mappedkeys[] = { -1 }; - -/* - * State bits to ignore when matching key or button events. By default, - * numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored. - */ -static uint ignoremod = Mod2Mask|XK_SWITCH_MOD; - -/* - * This is the huge key array which defines all compatibility to the Linux - * world. Please decide about changes wisely. - */ -static Key key[] = { - /* keysym mask string appkey appcursor */ - { XK_KP_Home, ShiftMask, "\033[2J", 0, -1}, - { XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1}, - { XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1}, - { XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1}, - { XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0}, - { XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1}, - { XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1}, - { XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0}, - { XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1}, - { XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1}, - { XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0}, - { XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1}, - { XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1}, - { XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0}, - { XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1}, - { XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1}, - { XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0}, - { XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, - { XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0}, - { XK_KP_End, ControlMask, "\033[J", -1, 0}, - { XK_KP_End, ControlMask, "\033[1;5F", +1, 0}, - { XK_KP_End, ShiftMask, "\033[K", -1, 0}, - { XK_KP_End, ShiftMask, "\033[1;2F", +1, 0}, - { XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0}, - { XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0}, - { XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0}, - { XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0}, - { XK_KP_Insert, ShiftMask, "\033[4l", -1, 0}, - { XK_KP_Insert, ControlMask, "\033[L", -1, 0}, - { XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0}, - { XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, - { XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, - { XK_KP_Delete, ControlMask, "\033[M", -1, 0}, - { XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0}, - { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0}, - { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0}, - { XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0}, - { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, - { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0}, - { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0}, - { XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0}, - { XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0}, - { XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0}, - { XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0}, - { XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0}, - { XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0}, - { XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0}, - { XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0}, - { XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0}, - { XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0}, - { XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0}, - { XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0}, - { XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0}, - { XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0}, - { XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0}, - { XK_Up, ShiftMask, "\033[1;2A", 0, 0}, - { XK_Up, Mod1Mask, "\033[1;3A", 0, 0}, - { XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0}, - { XK_Up, ControlMask, "\033[1;5A", 0, 0}, - { XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0}, - { XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0}, - { XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0}, - { XK_Up, XK_ANY_MOD, "\033[A", 0, -1}, - { XK_Up, XK_ANY_MOD, "\033OA", 0, +1}, - { XK_Down, ShiftMask, "\033[1;2B", 0, 0}, - { XK_Down, Mod1Mask, "\033[1;3B", 0, 0}, - { XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0}, - { XK_Down, ControlMask, "\033[1;5B", 0, 0}, - { XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0}, - { XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0}, - { XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0}, - { XK_Down, XK_ANY_MOD, "\033[B", 0, -1}, - { XK_Down, XK_ANY_MOD, "\033OB", 0, +1}, - { XK_Left, ShiftMask, "\033[1;2D", 0, 0}, - { XK_Left, Mod1Mask, "\033[1;3D", 0, 0}, - { XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0}, - { XK_Left, ControlMask, "\033[1;5D", 0, 0}, - { XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0}, - { XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0}, - { XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0}, - { XK_Left, XK_ANY_MOD, "\033[D", 0, -1}, - { XK_Left, XK_ANY_MOD, "\033OD", 0, +1}, - { XK_Right, ShiftMask, "\033[1;2C", 0, 0}, - { XK_Right, Mod1Mask, "\033[1;3C", 0, 0}, - { XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0}, - { XK_Right, ControlMask, "\033[1;5C", 0, 0}, - { XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0}, - { XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0}, - { XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0}, - { XK_Right, XK_ANY_MOD, "\033[C", 0, -1}, - { XK_Right, XK_ANY_MOD, "\033OC", 0, +1}, - { XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0}, - { XK_Return, Mod1Mask, "\033\r", 0, 0}, - { XK_Return, XK_ANY_MOD, "\r", 0, 0}, - { XK_Insert, ShiftMask, "\033[4l", -1, 0}, - { XK_Insert, ShiftMask, "\033[2;2~", +1, 0}, - { XK_Insert, ControlMask, "\033[L", -1, 0}, - { XK_Insert, ControlMask, "\033[2;5~", +1, 0}, - { XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, - { XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, - { XK_Delete, ControlMask, "\033[M", -1, 0}, - { XK_Delete, ControlMask, "\033[3;5~", +1, 0}, - { XK_Delete, ShiftMask, "\033[2K", -1, 0}, - { XK_Delete, ShiftMask, "\033[3;2~", +1, 0}, - { XK_Delete, XK_ANY_MOD, "\033[P", -1, 0}, - { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, - { XK_BackSpace, XK_NO_MOD, "\177", 0, 0}, - { XK_BackSpace, Mod1Mask, "\033\177", 0, 0}, - { XK_Home, ShiftMask, "\033[2J", 0, -1}, - { XK_Home, ShiftMask, "\033[1;2H", 0, +1}, - { XK_Home, XK_ANY_MOD, "\033[H", 0, -1}, - { XK_Home, XK_ANY_MOD, "\033[1~", 0, +1}, - { XK_End, ControlMask, "\033[J", -1, 0}, - { XK_End, ControlMask, "\033[1;5F", +1, 0}, - { XK_End, ShiftMask, "\033[K", -1, 0}, - { XK_End, ShiftMask, "\033[1;2F", +1, 0}, - { XK_End, XK_ANY_MOD, "\033[4~", 0, 0}, - { XK_Prior, ControlMask, "\033[5;5~", 0, 0}, - { XK_Prior, ShiftMask, "\033[5;2~", 0, 0}, - { XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, - { XK_Next, ControlMask, "\033[6;5~", 0, 0}, - { XK_Next, ShiftMask, "\033[6;2~", 0, 0}, - { XK_Next, XK_ANY_MOD, "\033[6~", 0, 0}, - { XK_F1, XK_NO_MOD, "\033OP" , 0, 0}, - { XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0}, - { XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0}, - { XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0}, - { XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0}, - { XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0}, - { XK_F2, XK_NO_MOD, "\033OQ" , 0, 0}, - { XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0}, - { XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0}, - { XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0}, - { XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0}, - { XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0}, - { XK_F3, XK_NO_MOD, "\033OR" , 0, 0}, - { XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0}, - { XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0}, - { XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0}, - { XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0}, - { XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0}, - { XK_F4, XK_NO_MOD, "\033OS" , 0, 0}, - { XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0}, - { XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0}, - { XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0}, - { XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0}, - { XK_F5, XK_NO_MOD, "\033[15~", 0, 0}, - { XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0}, - { XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0}, - { XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0}, - { XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0}, - { XK_F6, XK_NO_MOD, "\033[17~", 0, 0}, - { XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0}, - { XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0}, - { XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0}, - { XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0}, - { XK_F7, XK_NO_MOD, "\033[18~", 0, 0}, - { XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0}, - { XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0}, - { XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0}, - { XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0}, - { XK_F8, XK_NO_MOD, "\033[19~", 0, 0}, - { XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0}, - { XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0}, - { XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0}, - { XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0}, - { XK_F9, XK_NO_MOD, "\033[20~", 0, 0}, - { XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0}, - { XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0}, - { XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0}, - { XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0}, - { XK_F10, XK_NO_MOD, "\033[21~", 0, 0}, - { XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0}, - { XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0}, - { XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0}, - { XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0}, - { XK_F11, XK_NO_MOD, "\033[23~", 0, 0}, - { XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0}, - { XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0}, - { XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0}, - { XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0}, - { XK_F12, XK_NO_MOD, "\033[24~", 0, 0}, - { XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0}, - { XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0}, - { XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0}, - { XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0}, - { XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0}, - { XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0}, - { XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0}, - { XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0}, - { XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0}, - { XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0}, - { XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0}, - { XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0}, - { XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0}, - { XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0}, - { XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0}, - { XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0}, - { XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0}, - { XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0}, - { XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0}, - { XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0}, - { XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0}, - { XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0}, - { XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0}, - { XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0}, - { XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0}, - { XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0}, - { XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0}, -}; - -/* - * Selection types' masks. - * Use the same masks as usual. - * Button1Mask is always unset, to make masks match between ButtonPress. - * ButtonRelease and MotionNotify. - * If no match is found, regular selection is used. - */ -static uint selmasks[] = { - [SEL_RECTANGULAR] = Mod1Mask, -}; - -/* - * Printable characters in ASCII, used to estimate the advance width - * of single wide characters. - */ -static char ascii_printable[] = - " !\"#$%&'()*+,-./0123456789:;<=>?" - "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" - "`abcdefghijklmnopqrstuvwxyz{|}~"; diff --git a/st/config.def.h.rej b/st/config.def.h.rej deleted file mode 100644 index 8012bd9..0000000 --- a/st/config.def.h.rej +++ /dev/null @@ -1,10 +0,0 @@ ---- config.def.h -+++ config.def.h -@@ -6,6 +6,7 @@ - * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html - */ - static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true"; -+static char *font2 = "Roboto Mono for Powerline:pixelsize=12:antialias=true:autohint=true"; - static int borderpx = 2; - - /* diff --git a/st/config.h b/st/config.h deleted file mode 100644 index 3982f24..0000000 --- a/st/config.h +++ /dev/null @@ -1,468 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* - * appearance - * - * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html - */ -static char *font = "Mononoki:pixelsize=16:antialias=true:autohint=true"; -static char *font2 = "Joypixels:pixelsize=16:antialias=true:autohint=true"; - -static int borderpx = 2; - -/* - * What program is execed by st depends of these precedence rules: - * 1: program passed with -e - * 2: scroll and/or utmp - * 3: SHELL environment variable - * 4: value of shell in /etc/passwd - * 5: value of shell in config.h - */ -static char *shell = "/bin/sh"; -char *utmp = NULL; -/* scroll program: to enable use a string like "scroll" */ -char *scroll = NULL; -char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400"; - -/* identification sequence returned in DA and DECID */ -char *vtiden = "\033[?6c"; - -/* Kerning / character bounding-box multipliers */ -static float cwscale = 1.0; -static float chscale = 1.0; - -/* - * word delimiter string - * - * More advanced example: L" `'\"()[]{}" - */ -wchar_t *worddelimiters = L" "; - -/* selection timeouts (in milliseconds) */ -static unsigned int doubleclicktimeout = 300; -static unsigned int tripleclicktimeout = 600; - -/* alt screens */ -int allowaltscreen = 1; - -/* allow certain non-interactive (insecure) window operations such as: - setting the clipboard text */ -int allowwindowops = 0; - -/* - * draw latency range in ms - from new content/keypress/etc until drawing. - * within this range, st draws when content stops arriving (idle). mostly it's - * near minlatency, but it waits longer for slow updates to avoid partial draw. - * low minlatency will tear/flicker more, as it can "detect" idle too early. - */ -static double minlatency = 8; -static double maxlatency = 33; - -/* - * blinking timeout (set to 0 to disable blinking) for the terminal blinking - * attribute. - */ -static unsigned int blinktimeout = 800; - -/* - * thickness of underline and bar cursors - */ -static unsigned int cursorthickness = 2; - -/* - * bell volume. It must be a value between -100 and 100. Use 0 for disabling - * it - */ -static int bellvolume = 0; - -/* default TERM value */ -char *termname = "st-256color"; - -/* - * spaces per tab - * - * When you are changing this value, don't forget to adapt the »it« value in - * the st.info and appropriately install the st.info in the environment where - * you use this st version. - * - * it#$tabspaces, - * - * Secondly make sure your kernel is not expanding tabs. When running `stty - * -a` »tab0« should appear. You can tell the terminal to not expand tabs by - * running following command: - * - * stty tabs - */ -unsigned int tabspaces = 8; - -/* Terminal colors (16 first used in escape sequence) */ -static const char *colorname[] = { - - /* 8 normal colors */ - [0] = "#282828", /* hard contrast: #1d2021 / soft contrast: #32302f */ - [1] = "#cc241d", /* red */ - [2] = "#98971a", /* green */ - [3] = "#d79921", /* yellow */ - [4] = "#458588", /* blue */ - [5] = "#b16286", /* magenta */ - [6] = "#689d6a", /* cyan */ - [7] = "#a89984", /* white */ - - /* 8 bright colors */ - [8] = "#928374", /* black */ - [9] = "#fb4934", /* red */ - [10] = "#b8bb26", /* green */ - [11] = "#fabd2f", /* yellow */ - [12] = "#83a598", /* blue */ - [13] = "#d3869b", /* magenta */ - [14] = "#8ec07c", /* cyan */ - [15] = "#ebdbb2", /* white */ -}; - -/* - * Default colors (colorname index) - * foreground, background, cursor - */ -unsigned int defaultfg = 15; -unsigned int defaultbg = 0; -static unsigned int defaultcs = 15; -static unsigned int defaultrcs = 257; - -/* - * Default shape of cursor - * 2: Block ("█") - * 4: Underline ("_") - * 6: Bar ("|") - * 7: Snowman ("☃") - */ -static unsigned int cursorshape = 2; - -/* - * Default columns and rows numbers - */ - -static unsigned int cols = 80; -static unsigned int rows = 24; - -/* - * Default colour and shape of the mouse cursor - */ -static unsigned int mouseshape = XC_xterm; -static unsigned int mousefg = 7; -static unsigned int mousebg = 0; - -/* - * Color used to display font attributes when fontconfig selected a font which - * doesn't match the ones requested. - */ -static unsigned int defaultattr = 11; - -/* - * Force mouse select/shortcuts while mask is active (when MODE_MOUSE is set). - * Note that if you want to use ShiftMask with selmasks, set this to an other - * modifier, set to 0 to not use it. - */ -static uint forcemousemod = ShiftMask; - -/* - * Internal mouse shortcuts. - * Beware that overloading Button1 will disable the selection. - */ -static MouseShortcut mshortcuts[] = { - /* mask button function argument release */ - { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 }, - { ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} }, - { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} }, - { ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} }, - { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} }, -}; - -/* Internal keyboard shortcuts. */ -#define MODKEY Mod1Mask -#define TERMMOD (ControlMask|ShiftMask) - -static Shortcut shortcuts[] = { - /* mask keysym function argument */ - { XK_ANY_MOD, XK_Break, sendbreak, {.i = 0} }, - { ControlMask, XK_Print, toggleprinter, {.i = 0} }, - { ShiftMask, XK_Print, printscreen, {.i = 0} }, - { XK_ANY_MOD, XK_Print, printsel, {.i = 0} }, - { TERMMOD, XK_Prior, zoom, {.f = +1} }, - { TERMMOD, XK_Next, zoom, {.f = -1} }, - { TERMMOD, XK_Home, zoomreset, {.f = 0} }, - { TERMMOD, XK_C, clipcopy, {.i = 0} }, - { TERMMOD, XK_V, clippaste, {.i = 0} }, - { TERMMOD, XK_Y, selpaste, {.i = 0} }, - { ShiftMask, XK_Insert, selpaste, {.i = 0} }, - { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, -}; - -/* - * Special keys (change & recompile st.info accordingly) - * - * Mask value: - * * Use XK_ANY_MOD to match the key no matter modifiers state - * * Use XK_NO_MOD to match the key alone (no modifiers) - * appkey value: - * * 0: no value - * * > 0: keypad application mode enabled - * * = 2: term.numlock = 1 - * * < 0: keypad application mode disabled - * appcursor value: - * * 0: no value - * * > 0: cursor application mode enabled - * * < 0: cursor application mode disabled - * - * Be careful with the order of the definitions because st searches in - * this table sequentially, so any XK_ANY_MOD must be in the last - * position for a key. - */ - -/* - * If you want keys other than the X11 function keys (0xFD00 - 0xFFFF) - * to be mapped below, add them to this array. - */ -static KeySym mappedkeys[] = { -1 }; - -/* - * State bits to ignore when matching key or button events. By default, - * numlock (Mod2Mask) and keyboard layout (XK_SWITCH_MOD) are ignored. - */ -static uint ignoremod = Mod2Mask|XK_SWITCH_MOD; - -/* - * This is the huge key array which defines all compatibility to the Linux - * world. Please decide about changes wisely. - */ -static Key key[] = { - /* keysym mask string appkey appcursor */ - { XK_KP_Home, ShiftMask, "\033[2J", 0, -1}, - { XK_KP_Home, ShiftMask, "\033[1;2H", 0, +1}, - { XK_KP_Home, XK_ANY_MOD, "\033[H", 0, -1}, - { XK_KP_Home, XK_ANY_MOD, "\033[1~", 0, +1}, - { XK_KP_Up, XK_ANY_MOD, "\033Ox", +1, 0}, - { XK_KP_Up, XK_ANY_MOD, "\033[A", 0, -1}, - { XK_KP_Up, XK_ANY_MOD, "\033OA", 0, +1}, - { XK_KP_Down, XK_ANY_MOD, "\033Or", +1, 0}, - { XK_KP_Down, XK_ANY_MOD, "\033[B", 0, -1}, - { XK_KP_Down, XK_ANY_MOD, "\033OB", 0, +1}, - { XK_KP_Left, XK_ANY_MOD, "\033Ot", +1, 0}, - { XK_KP_Left, XK_ANY_MOD, "\033[D", 0, -1}, - { XK_KP_Left, XK_ANY_MOD, "\033OD", 0, +1}, - { XK_KP_Right, XK_ANY_MOD, "\033Ov", +1, 0}, - { XK_KP_Right, XK_ANY_MOD, "\033[C", 0, -1}, - { XK_KP_Right, XK_ANY_MOD, "\033OC", 0, +1}, - { XK_KP_Prior, ShiftMask, "\033[5;2~", 0, 0}, - { XK_KP_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, - { XK_KP_Begin, XK_ANY_MOD, "\033[E", 0, 0}, - { XK_KP_End, ControlMask, "\033[J", -1, 0}, - { XK_KP_End, ControlMask, "\033[1;5F", +1, 0}, - { XK_KP_End, ShiftMask, "\033[K", -1, 0}, - { XK_KP_End, ShiftMask, "\033[1;2F", +1, 0}, - { XK_KP_End, XK_ANY_MOD, "\033[4~", 0, 0}, - { XK_KP_Next, ShiftMask, "\033[6;2~", 0, 0}, - { XK_KP_Next, XK_ANY_MOD, "\033[6~", 0, 0}, - { XK_KP_Insert, ShiftMask, "\033[2;2~", +1, 0}, - { XK_KP_Insert, ShiftMask, "\033[4l", -1, 0}, - { XK_KP_Insert, ControlMask, "\033[L", -1, 0}, - { XK_KP_Insert, ControlMask, "\033[2;5~", +1, 0}, - { XK_KP_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, - { XK_KP_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, - { XK_KP_Delete, ControlMask, "\033[M", -1, 0}, - { XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0}, - { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0}, - { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0}, - { XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0}, - { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, - { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0}, - { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0}, - { XK_KP_Enter, XK_ANY_MOD, "\033OM", +2, 0}, - { XK_KP_Enter, XK_ANY_MOD, "\r", -1, 0}, - { XK_KP_Subtract, XK_ANY_MOD, "\033Om", +2, 0}, - { XK_KP_Decimal, XK_ANY_MOD, "\033On", +2, 0}, - { XK_KP_Divide, XK_ANY_MOD, "\033Oo", +2, 0}, - { XK_KP_0, XK_ANY_MOD, "\033Op", +2, 0}, - { XK_KP_1, XK_ANY_MOD, "\033Oq", +2, 0}, - { XK_KP_2, XK_ANY_MOD, "\033Or", +2, 0}, - { XK_KP_3, XK_ANY_MOD, "\033Os", +2, 0}, - { XK_KP_4, XK_ANY_MOD, "\033Ot", +2, 0}, - { XK_KP_5, XK_ANY_MOD, "\033Ou", +2, 0}, - { XK_KP_6, XK_ANY_MOD, "\033Ov", +2, 0}, - { XK_KP_7, XK_ANY_MOD, "\033Ow", +2, 0}, - { XK_KP_8, XK_ANY_MOD, "\033Ox", +2, 0}, - { XK_KP_9, XK_ANY_MOD, "\033Oy", +2, 0}, - { XK_Up, ShiftMask, "\033[1;2A", 0, 0}, - { XK_Up, Mod1Mask, "\033[1;3A", 0, 0}, - { XK_Up, ShiftMask|Mod1Mask,"\033[1;4A", 0, 0}, - { XK_Up, ControlMask, "\033[1;5A", 0, 0}, - { XK_Up, ShiftMask|ControlMask,"\033[1;6A", 0, 0}, - { XK_Up, ControlMask|Mod1Mask,"\033[1;7A", 0, 0}, - { XK_Up,ShiftMask|ControlMask|Mod1Mask,"\033[1;8A", 0, 0}, - { XK_Up, XK_ANY_MOD, "\033[A", 0, -1}, - { XK_Up, XK_ANY_MOD, "\033OA", 0, +1}, - { XK_Down, ShiftMask, "\033[1;2B", 0, 0}, - { XK_Down, Mod1Mask, "\033[1;3B", 0, 0}, - { XK_Down, ShiftMask|Mod1Mask,"\033[1;4B", 0, 0}, - { XK_Down, ControlMask, "\033[1;5B", 0, 0}, - { XK_Down, ShiftMask|ControlMask,"\033[1;6B", 0, 0}, - { XK_Down, ControlMask|Mod1Mask,"\033[1;7B", 0, 0}, - { XK_Down,ShiftMask|ControlMask|Mod1Mask,"\033[1;8B",0, 0}, - { XK_Down, XK_ANY_MOD, "\033[B", 0, -1}, - { XK_Down, XK_ANY_MOD, "\033OB", 0, +1}, - { XK_Left, ShiftMask, "\033[1;2D", 0, 0}, - { XK_Left, Mod1Mask, "\033[1;3D", 0, 0}, - { XK_Left, ShiftMask|Mod1Mask,"\033[1;4D", 0, 0}, - { XK_Left, ControlMask, "\033[1;5D", 0, 0}, - { XK_Left, ShiftMask|ControlMask,"\033[1;6D", 0, 0}, - { XK_Left, ControlMask|Mod1Mask,"\033[1;7D", 0, 0}, - { XK_Left,ShiftMask|ControlMask|Mod1Mask,"\033[1;8D",0, 0}, - { XK_Left, XK_ANY_MOD, "\033[D", 0, -1}, - { XK_Left, XK_ANY_MOD, "\033OD", 0, +1}, - { XK_Right, ShiftMask, "\033[1;2C", 0, 0}, - { XK_Right, Mod1Mask, "\033[1;3C", 0, 0}, - { XK_Right, ShiftMask|Mod1Mask,"\033[1;4C", 0, 0}, - { XK_Right, ControlMask, "\033[1;5C", 0, 0}, - { XK_Right, ShiftMask|ControlMask,"\033[1;6C", 0, 0}, - { XK_Right, ControlMask|Mod1Mask,"\033[1;7C", 0, 0}, - { XK_Right,ShiftMask|ControlMask|Mod1Mask,"\033[1;8C",0, 0}, - { XK_Right, XK_ANY_MOD, "\033[C", 0, -1}, - { XK_Right, XK_ANY_MOD, "\033OC", 0, +1}, - { XK_ISO_Left_Tab, ShiftMask, "\033[Z", 0, 0}, - { XK_Return, Mod1Mask, "\033\r", 0, 0}, - { XK_Return, XK_ANY_MOD, "\r", 0, 0}, - { XK_Insert, ShiftMask, "\033[4l", -1, 0}, - { XK_Insert, ShiftMask, "\033[2;2~", +1, 0}, - { XK_Insert, ControlMask, "\033[L", -1, 0}, - { XK_Insert, ControlMask, "\033[2;5~", +1, 0}, - { XK_Insert, XK_ANY_MOD, "\033[4h", -1, 0}, - { XK_Insert, XK_ANY_MOD, "\033[2~", +1, 0}, - { XK_Delete, ControlMask, "\033[M", -1, 0}, - { XK_Delete, ControlMask, "\033[3;5~", +1, 0}, - { XK_Delete, ShiftMask, "\033[2K", -1, 0}, - { XK_Delete, ShiftMask, "\033[3;2~", +1, 0}, - { XK_Delete, XK_ANY_MOD, "\033[P", -1, 0}, - { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0}, - { XK_BackSpace, XK_NO_MOD, "\177", 0, 0}, - { XK_BackSpace, Mod1Mask, "\033\177", 0, 0}, - { XK_Home, ShiftMask, "\033[2J", 0, -1}, - { XK_Home, ShiftMask, "\033[1;2H", 0, +1}, - { XK_Home, XK_ANY_MOD, "\033[H", 0, -1}, - { XK_Home, XK_ANY_MOD, "\033[1~", 0, +1}, - { XK_End, ControlMask, "\033[J", -1, 0}, - { XK_End, ControlMask, "\033[1;5F", +1, 0}, - { XK_End, ShiftMask, "\033[K", -1, 0}, - { XK_End, ShiftMask, "\033[1;2F", +1, 0}, - { XK_End, XK_ANY_MOD, "\033[4~", 0, 0}, - { XK_Prior, ControlMask, "\033[5;5~", 0, 0}, - { XK_Prior, ShiftMask, "\033[5;2~", 0, 0}, - { XK_Prior, XK_ANY_MOD, "\033[5~", 0, 0}, - { XK_Next, ControlMask, "\033[6;5~", 0, 0}, - { XK_Next, ShiftMask, "\033[6;2~", 0, 0}, - { XK_Next, XK_ANY_MOD, "\033[6~", 0, 0}, - { XK_F1, XK_NO_MOD, "\033OP" , 0, 0}, - { XK_F1, /* F13 */ ShiftMask, "\033[1;2P", 0, 0}, - { XK_F1, /* F25 */ ControlMask, "\033[1;5P", 0, 0}, - { XK_F1, /* F37 */ Mod4Mask, "\033[1;6P", 0, 0}, - { XK_F1, /* F49 */ Mod1Mask, "\033[1;3P", 0, 0}, - { XK_F1, /* F61 */ Mod3Mask, "\033[1;4P", 0, 0}, - { XK_F2, XK_NO_MOD, "\033OQ" , 0, 0}, - { XK_F2, /* F14 */ ShiftMask, "\033[1;2Q", 0, 0}, - { XK_F2, /* F26 */ ControlMask, "\033[1;5Q", 0, 0}, - { XK_F2, /* F38 */ Mod4Mask, "\033[1;6Q", 0, 0}, - { XK_F2, /* F50 */ Mod1Mask, "\033[1;3Q", 0, 0}, - { XK_F2, /* F62 */ Mod3Mask, "\033[1;4Q", 0, 0}, - { XK_F3, XK_NO_MOD, "\033OR" , 0, 0}, - { XK_F3, /* F15 */ ShiftMask, "\033[1;2R", 0, 0}, - { XK_F3, /* F27 */ ControlMask, "\033[1;5R", 0, 0}, - { XK_F3, /* F39 */ Mod4Mask, "\033[1;6R", 0, 0}, - { XK_F3, /* F51 */ Mod1Mask, "\033[1;3R", 0, 0}, - { XK_F3, /* F63 */ Mod3Mask, "\033[1;4R", 0, 0}, - { XK_F4, XK_NO_MOD, "\033OS" , 0, 0}, - { XK_F4, /* F16 */ ShiftMask, "\033[1;2S", 0, 0}, - { XK_F4, /* F28 */ ControlMask, "\033[1;5S", 0, 0}, - { XK_F4, /* F40 */ Mod4Mask, "\033[1;6S", 0, 0}, - { XK_F4, /* F52 */ Mod1Mask, "\033[1;3S", 0, 0}, - { XK_F5, XK_NO_MOD, "\033[15~", 0, 0}, - { XK_F5, /* F17 */ ShiftMask, "\033[15;2~", 0, 0}, - { XK_F5, /* F29 */ ControlMask, "\033[15;5~", 0, 0}, - { XK_F5, /* F41 */ Mod4Mask, "\033[15;6~", 0, 0}, - { XK_F5, /* F53 */ Mod1Mask, "\033[15;3~", 0, 0}, - { XK_F6, XK_NO_MOD, "\033[17~", 0, 0}, - { XK_F6, /* F18 */ ShiftMask, "\033[17;2~", 0, 0}, - { XK_F6, /* F30 */ ControlMask, "\033[17;5~", 0, 0}, - { XK_F6, /* F42 */ Mod4Mask, "\033[17;6~", 0, 0}, - { XK_F6, /* F54 */ Mod1Mask, "\033[17;3~", 0, 0}, - { XK_F7, XK_NO_MOD, "\033[18~", 0, 0}, - { XK_F7, /* F19 */ ShiftMask, "\033[18;2~", 0, 0}, - { XK_F7, /* F31 */ ControlMask, "\033[18;5~", 0, 0}, - { XK_F7, /* F43 */ Mod4Mask, "\033[18;6~", 0, 0}, - { XK_F7, /* F55 */ Mod1Mask, "\033[18;3~", 0, 0}, - { XK_F8, XK_NO_MOD, "\033[19~", 0, 0}, - { XK_F8, /* F20 */ ShiftMask, "\033[19;2~", 0, 0}, - { XK_F8, /* F32 */ ControlMask, "\033[19;5~", 0, 0}, - { XK_F8, /* F44 */ Mod4Mask, "\033[19;6~", 0, 0}, - { XK_F8, /* F56 */ Mod1Mask, "\033[19;3~", 0, 0}, - { XK_F9, XK_NO_MOD, "\033[20~", 0, 0}, - { XK_F9, /* F21 */ ShiftMask, "\033[20;2~", 0, 0}, - { XK_F9, /* F33 */ ControlMask, "\033[20;5~", 0, 0}, - { XK_F9, /* F45 */ Mod4Mask, "\033[20;6~", 0, 0}, - { XK_F9, /* F57 */ Mod1Mask, "\033[20;3~", 0, 0}, - { XK_F10, XK_NO_MOD, "\033[21~", 0, 0}, - { XK_F10, /* F22 */ ShiftMask, "\033[21;2~", 0, 0}, - { XK_F10, /* F34 */ ControlMask, "\033[21;5~", 0, 0}, - { XK_F10, /* F46 */ Mod4Mask, "\033[21;6~", 0, 0}, - { XK_F10, /* F58 */ Mod1Mask, "\033[21;3~", 0, 0}, - { XK_F11, XK_NO_MOD, "\033[23~", 0, 0}, - { XK_F11, /* F23 */ ShiftMask, "\033[23;2~", 0, 0}, - { XK_F11, /* F35 */ ControlMask, "\033[23;5~", 0, 0}, - { XK_F11, /* F47 */ Mod4Mask, "\033[23;6~", 0, 0}, - { XK_F11, /* F59 */ Mod1Mask, "\033[23;3~", 0, 0}, - { XK_F12, XK_NO_MOD, "\033[24~", 0, 0}, - { XK_F12, /* F24 */ ShiftMask, "\033[24;2~", 0, 0}, - { XK_F12, /* F36 */ ControlMask, "\033[24;5~", 0, 0}, - { XK_F12, /* F48 */ Mod4Mask, "\033[24;6~", 0, 0}, - { XK_F12, /* F60 */ Mod1Mask, "\033[24;3~", 0, 0}, - { XK_F13, XK_NO_MOD, "\033[1;2P", 0, 0}, - { XK_F14, XK_NO_MOD, "\033[1;2Q", 0, 0}, - { XK_F15, XK_NO_MOD, "\033[1;2R", 0, 0}, - { XK_F16, XK_NO_MOD, "\033[1;2S", 0, 0}, - { XK_F17, XK_NO_MOD, "\033[15;2~", 0, 0}, - { XK_F18, XK_NO_MOD, "\033[17;2~", 0, 0}, - { XK_F19, XK_NO_MOD, "\033[18;2~", 0, 0}, - { XK_F20, XK_NO_MOD, "\033[19;2~", 0, 0}, - { XK_F21, XK_NO_MOD, "\033[20;2~", 0, 0}, - { XK_F22, XK_NO_MOD, "\033[21;2~", 0, 0}, - { XK_F23, XK_NO_MOD, "\033[23;2~", 0, 0}, - { XK_F24, XK_NO_MOD, "\033[24;2~", 0, 0}, - { XK_F25, XK_NO_MOD, "\033[1;5P", 0, 0}, - { XK_F26, XK_NO_MOD, "\033[1;5Q", 0, 0}, - { XK_F27, XK_NO_MOD, "\033[1;5R", 0, 0}, - { XK_F28, XK_NO_MOD, "\033[1;5S", 0, 0}, - { XK_F29, XK_NO_MOD, "\033[15;5~", 0, 0}, - { XK_F30, XK_NO_MOD, "\033[17;5~", 0, 0}, - { XK_F31, XK_NO_MOD, "\033[18;5~", 0, 0}, - { XK_F32, XK_NO_MOD, "\033[19;5~", 0, 0}, - { XK_F33, XK_NO_MOD, "\033[20;5~", 0, 0}, - { XK_F34, XK_NO_MOD, "\033[21;5~", 0, 0}, - { XK_F35, XK_NO_MOD, "\033[23;5~", 0, 0}, -}; - -/* - * Selection types' masks. - * Use the same masks as usual. - * Button1Mask is always unset, to make masks match between ButtonPress. - * ButtonRelease and MotionNotify. - * If no match is found, regular selection is used. - */ -static uint selmasks[] = { - [SEL_RECTANGULAR] = Mod1Mask, -}; - -/* - * Printable characters in ASCII, used to estimate the advance width - * of single wide characters. - */ -static char ascii_printable[] = - " !\"#$%&'()*+,-./0123456789:;<=>?" - "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" - "`abcdefghijklmnopqrstuvwxyz{|}~"; diff --git a/st/config.mk b/st/config.mk deleted file mode 100644 index c070a4a..0000000 --- a/st/config.mk +++ /dev/null @@ -1,35 +0,0 @@ -# st version -VERSION = 0.8.4 - -# Customize below to fit your system - -# paths -PREFIX = /usr/local -MANPREFIX = $(PREFIX)/share/man - -X11INC = /usr/X11R6/include -X11LIB = /usr/X11R6/lib - -PKG_CONFIG = pkg-config - -# includes and libs -INCS = -I$(X11INC) \ - `$(PKG_CONFIG) --cflags fontconfig` \ - `$(PKG_CONFIG) --cflags freetype2` -LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \ - `$(PKG_CONFIG) --libs fontconfig` \ - `$(PKG_CONFIG) --libs freetype2` - -# flags -STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 -STCFLAGS = $(INCS) $(STCPPFLAGS) $(CPPFLAGS) $(CFLAGS) -STLDFLAGS = $(LIBS) $(LDFLAGS) - -# OpenBSD: -#CPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -#LIBS = -L$(X11LIB) -lm -lX11 -lutil -lXft \ -# `$(PKG_CONFIG) --libs fontconfig` \ -# `$(PKG_CONFIG) --libs freetype2` - -# compiler and linker -# CC = c99 diff --git a/st/patches/st-font2-20190326-f64c2f8.diff b/st/patches/st-font2-20190326-f64c2f8.diff deleted file mode 100644 index fdb6efe..0000000 --- a/st/patches/st-font2-20190326-f64c2f8.diff +++ /dev/null @@ -1,126 +0,0 @@ -From f64c2f83a2e3ee349fe11100526110dfdf47067a Mon Sep 17 00:00:00 2001 -From: Kirill Bugaev -Date: Wed, 27 Mar 2019 01:28:56 +0800 -Subject: [PATCH] Some glyphs can be not present in font defined by default. - For this glyphs st uses font-config and try to find them in font cache first. - This patch append font defined in `font2` variable to the beginning of font - cache. So it will be used as spare font. - ---- - config.def.h | 1 + - x.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 67 insertions(+) - -diff --git a/config.def.h b/config.def.h -index 482901e..88eee0f 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -6,6 +6,7 @@ - * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html - */ - static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true"; -+static char *font2 = "Roboto Mono for Powerline:pixelsize=12:antialias=true:autohint=true"; - static int borderpx = 2; - - /* -diff --git a/x.c b/x.c -index 5828a3b..052b10b 100644 ---- a/x.c -+++ b/x.c -@@ -149,6 +149,7 @@ static void xhints(void); - static int xloadcolor(int, const char *, Color *); - static int xloadfont(Font *, FcPattern *); - static void xloadfonts(char *, double); -+static void xloadsparefont(); - static void xunloadfont(Font *); - static void xunloadfonts(void); - static void xsetenv(void); -@@ -296,6 +297,7 @@ zoomabs(const Arg *arg) - { - xunloadfonts(); - xloadfonts(usedfont, arg->f); -+ xloadsparefont(); - cresize(0, 0); - redraw(); - xhints(); -@@ -977,6 +979,67 @@ xloadfonts(char *fontstr, double fontsize) - FcPatternDestroy(pattern); - } - -+void -+xloadsparefont() -+{ -+ FcPattern *fontpattern, *match; -+ FcResult result; -+ -+ /* add font2 to font cache as first 4 entries */ -+ if ( font2[0] == '-' ) -+ fontpattern = XftXlfdParse(font2, False, False); -+ else -+ fontpattern = FcNameParse((FcChar8 *)font2); -+ if ( fontpattern ) { -+ /* Allocate memory for the new cache entries. */ -+ frccap += 4; -+ frc = xrealloc(frc, frccap * sizeof(Fontcache)); -+ /* add Normal */ -+ match = FcFontMatch(NULL, fontpattern, &result); -+ if ( match ) -+ frc[frclen].font = XftFontOpenPattern(xw.dpy, match); -+ if ( frc[frclen].font ) { -+ frc[frclen].flags = FRC_NORMAL; -+ frclen++; -+ } else -+ FcPatternDestroy(match); -+ /* add Italic */ -+ FcPatternDel(fontpattern, FC_SLANT); -+ FcPatternAddInteger(fontpattern, FC_SLANT, FC_SLANT_ITALIC); -+ match = FcFontMatch(NULL, fontpattern, &result); -+ if ( match ) -+ frc[frclen].font = XftFontOpenPattern(xw.dpy, match); -+ if ( frc[frclen].font ) { -+ frc[frclen].flags = FRC_ITALIC; -+ frclen++; -+ } else -+ FcPatternDestroy(match); -+ /* add Italic Bold */ -+ FcPatternDel(fontpattern, FC_WEIGHT); -+ FcPatternAddInteger(fontpattern, FC_WEIGHT, FC_WEIGHT_BOLD); -+ match = FcFontMatch(NULL, fontpattern, &result); -+ if ( match ) -+ frc[frclen].font = XftFontOpenPattern(xw.dpy, match); -+ if ( frc[frclen].font ) { -+ frc[frclen].flags = FRC_ITALICBOLD; -+ frclen++; -+ } else -+ FcPatternDestroy(match); -+ /* add Bold */ -+ FcPatternDel(fontpattern, FC_SLANT); -+ FcPatternAddInteger(fontpattern, FC_SLANT, FC_SLANT_ROMAN); -+ match = FcFontMatch(NULL, fontpattern, &result); -+ if ( match ) -+ frc[frclen].font = XftFontOpenPattern(xw.dpy, match); -+ if ( frc[frclen].font ) { -+ frc[frclen].flags = FRC_BOLD; -+ frclen++; -+ } else -+ FcPatternDestroy(match); -+ FcPatternDestroy(fontpattern); -+ } -+} -+ - void - xunloadfont(Font *f) - { -@@ -1057,6 +1120,9 @@ xinit(int cols, int rows) - usedfont = (opt_font == NULL)? font : opt_font; - xloadfonts(usedfont, 0); - -+ /* spare font (font2) */ -+ xloadsparefont(); -+ - /* colors */ - xw.cmap = XDefaultColormap(xw.dpy, xw.scr); - xloadcols(); --- -2.21.0 - diff --git a/st/patches/st-gruvbox-dark-0.8.2.diff b/st/patches/st-gruvbox-dark-0.8.2.diff deleted file mode 100644 index c8390f0..0000000 --- a/st/patches/st-gruvbox-dark-0.8.2.diff +++ /dev/null @@ -1,70 +0,0 @@ -diff --git a/config.def.h b/config.def.h -index 877afab..6a1699f 100644 ---- a/config.def.h -+++ b/config.def.h -@@ -84,41 +84,35 @@ static unsigned int tabspaces = 8; - - /* Terminal colors (16 first used in escape sequence) */ - static const char *colorname[] = { -- /* 8 normal colors */ -- "black", -- "red3", -- "green3", -- "yellow3", -- "blue2", -- "magenta3", -- "cyan3", -- "gray90", -- -- /* 8 bright colors */ -- "gray50", -- "red", -- "green", -- "yellow", -- "#5c5cff", -- "magenta", -- "cyan", -- "white", -- -- [255] = 0, -- -- /* more colors can be added after 255 to use with DefaultXX */ -- "#cccccc", -- "#555555", --}; - -+ /* 8 normal colors */ -+ [0] = "#282828", /* hard contrast: #1d2021 / soft contrast: #32302f */ -+ [1] = "#cc241d", /* red */ -+ [2] = "#98971a", /* green */ -+ [3] = "#d79921", /* yellow */ -+ [4] = "#458588", /* blue */ -+ [5] = "#b16286", /* magenta */ -+ [6] = "#689d6a", /* cyan */ -+ [7] = "#a89984", /* white */ -+ -+ /* 8 bright colors */ -+ [8] = "#928374", /* black */ -+ [9] = "#fb4934", /* red */ -+ [10] = "#b8bb26", /* green */ -+ [11] = "#fabd2f", /* yellow */ -+ [12] = "#83a598", /* blue */ -+ [13] = "#d3869b", /* magenta */ -+ [14] = "#8ec07c", /* cyan */ -+ [15] = "#ebdbb2", /* white */ -+}; - - /* - * Default colors (colorname index) -- * foreground, background, cursor, reverse cursor -+ * foreground, background, cursor - */ --unsigned int defaultfg = 7; --unsigned int defaultbg = 0; --static unsigned int defaultcs = 256; -+unsigned int defaultfg = 15; -+unsigned int defaultbg = 0; -+static unsigned int defaultcs = 15; - static unsigned int defaultrcs = 257; - - /* diff --git a/st/st b/st/st deleted file mode 100755 index bfbcabe3074b6f5f3ccd8dcbd11d61c2711974ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 104904 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 Q|CC-d$1hzML3gYDKTj8V!~g&Q diff --git a/st/st.1 b/st/st.1 deleted file mode 100644 index 39120b4..0000000 --- a/st/st.1 +++ /dev/null @@ -1,177 +0,0 @@ -.TH ST 1 st\-VERSION -.SH NAME -st \- simple terminal -.SH SYNOPSIS -.B st -.RB [ \-aiv ] -.RB [ \-c -.IR class ] -.RB [ \-f -.IR font ] -.RB [ \-g -.IR geometry ] -.RB [ \-n -.IR name ] -.RB [ \-o -.IR iofile ] -.RB [ \-T -.IR title ] -.RB [ \-t -.IR title ] -.RB [ \-l -.IR line ] -.RB [ \-w -.IR windowid ] -.RB [[ \-e ] -.IR command -.RI [ arguments ...]] -.PP -.B st -.RB [ \-aiv ] -.RB [ \-c -.IR class ] -.RB [ \-f -.IR font ] -.RB [ \-g -.IR geometry ] -.RB [ \-n -.IR name ] -.RB [ \-o -.IR iofile ] -.RB [ \-T -.IR title ] -.RB [ \-t -.IR title ] -.RB [ \-w -.IR windowid ] -.RB \-l -.IR line -.RI [ stty_args ...] -.SH DESCRIPTION -.B st -is a simple terminal emulator. -.SH OPTIONS -.TP -.B \-a -disable alternate screens in terminal -.TP -.BI \-c " class" -defines the window class (default $TERM). -.TP -.BI \-f " font" -defines the -.I font -to use when st is run. -.TP -.BI \-g " geometry" -defines the X11 geometry string. -The form is [=][{xX}][{+-}{+-}]. See -.BR XParseGeometry (3) -for further details. -.TP -.B \-i -will fixate the position given with the -g option. -.TP -.BI \-n " name" -defines the window instance name (default $TERM). -.TP -.BI \-o " iofile" -writes all the I/O to -.I iofile. -This feature is useful when recording st sessions. A value of "-" means -standard output. -.TP -.BI \-T " title" -defines the window title (default 'st'). -.TP -.BI \-t " title" -defines the window title (default 'st'). -.TP -.BI \-w " windowid" -embeds st within the window identified by -.I windowid -.TP -.BI \-l " line" -use a tty -.I line -instead of a pseudo terminal. -.I line -should be a (pseudo-)serial device (e.g. /dev/ttyS0 on Linux for serial port -0). -When this flag is given -remaining arguments are used as flags for -.BR stty(1). -By default st initializes the serial line to 8 bits, no parity, 1 stop bit -and a 38400 baud rate. The speed is set by appending it as last argument -(e.g. 'st -l /dev/ttyS0 115200'). Arguments before the last one are -.BR stty(1) -flags. If you want to set odd parity on 115200 baud use for example 'st -l -/dev/ttyS0 parenb parodd 115200'. Set the number of bits by using for -example 'st -l /dev/ttyS0 cs7 115200'. See -.BR stty(1) -for more arguments and cases. -.TP -.B \-v -prints version information to stderr, then exits. -.TP -.BI \-e " command " [ " arguments " "... ]" -st executes -.I command -instead of the shell. If this is used it -.B must be the last option -on the command line, as in xterm / rxvt. -This option is only intended for compatibility, -and all the remaining arguments are used as a command -even without it. -.SH SHORTCUTS -.TP -.B Break -Send a break in the serial line. -Break key is obtained in PC keyboards -pressing at the same time control and pause. -.TP -.B Ctrl-Print Screen -Toggle if st should print to the -.I iofile. -.TP -.B Shift-Print Screen -Print the full screen to the -.I iofile. -.TP -.B Print Screen -Print the selection to the -.I iofile. -.TP -.B Ctrl-Shift-Page Up -Increase font size. -.TP -.B Ctrl-Shift-Page Down -Decrease font size. -.TP -.B Ctrl-Shift-Home -Reset to default font size. -.TP -.B Ctrl-Shift-y -Paste from primary selection (middle mouse button). -.TP -.B Ctrl-Shift-c -Copy the selected text to the clipboard selection. -.TP -.B Ctrl-Shift-v -Paste from the clipboard selection. -.SH CUSTOMIZATION -.B st -can be customized by creating a custom config.h and (re)compiling the source -code. This keeps it fast, secure and simple. -.SH AUTHORS -See the LICENSE file for the authors. -.SH LICENSE -See the LICENSE file for the terms of redistribution. -.SH SEE ALSO -.BR tabbed (1), -.BR utmp (1), -.BR stty (1), -.BR scroll (1) -.SH BUGS -See the TODO file in the distribution. - diff --git a/st/st.c b/st/st.c deleted file mode 100644 index abbbe4b..0000000 --- a/st/st.c +++ /dev/null @@ -1,2605 +0,0 @@ -/* See LICENSE for license details. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "st.h" -#include "win.h" - -#if defined(__linux) - #include -#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) - #include -#elif defined(__FreeBSD__) || defined(__DragonFly__) - #include -#endif - -/* Arbitrary sizes */ -#define UTF_INVALID 0xFFFD -#define UTF_SIZ 4 -#define ESC_BUF_SIZ (128*UTF_SIZ) -#define ESC_ARG_SIZ 16 -#define STR_BUF_SIZ ESC_BUF_SIZ -#define STR_ARG_SIZ ESC_ARG_SIZ - -/* macros */ -#define IS_SET(flag) ((term.mode & (flag)) != 0) -#define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == 0x7f) -#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f)) -#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c)) -#define ISDELIM(u) (u && wcschr(worddelimiters, u)) - -enum term_mode { - MODE_WRAP = 1 << 0, - MODE_INSERT = 1 << 1, - MODE_ALTSCREEN = 1 << 2, - MODE_CRLF = 1 << 3, - MODE_ECHO = 1 << 4, - MODE_PRINT = 1 << 5, - MODE_UTF8 = 1 << 6, -}; - -enum cursor_movement { - CURSOR_SAVE, - CURSOR_LOAD -}; - -enum cursor_state { - CURSOR_DEFAULT = 0, - CURSOR_WRAPNEXT = 1, - CURSOR_ORIGIN = 2 -}; - -enum charset { - CS_GRAPHIC0, - CS_GRAPHIC1, - CS_UK, - CS_USA, - CS_MULTI, - CS_GER, - CS_FIN -}; - -enum escape_state { - ESC_START = 1, - ESC_CSI = 2, - ESC_STR = 4, /* DCS, OSC, PM, APC */ - ESC_ALTCHARSET = 8, - ESC_STR_END = 16, /* a final string was encountered */ - ESC_TEST = 32, /* Enter in test mode */ - ESC_UTF8 = 64, -}; - -typedef struct { - Glyph attr; /* current char attributes */ - int x; - int y; - char state; -} TCursor; - -typedef struct { - int mode; - int type; - int snap; - /* - * Selection variables: - * nb – normalized coordinates of the beginning of the selection - * ne – normalized coordinates of the end of the selection - * ob – original coordinates of the beginning of the selection - * oe – original coordinates of the end of the selection - */ - struct { - int x, y; - } nb, ne, ob, oe; - - int alt; -} Selection; - -/* Internal representation of the screen */ -typedef struct { - int row; /* nb row */ - int col; /* nb col */ - Line *line; /* screen */ - Line *alt; /* alternate screen */ - int *dirty; /* dirtyness of lines */ - TCursor c; /* cursor */ - int ocx; /* old cursor col */ - int ocy; /* old cursor row */ - int top; /* top scroll limit */ - int bot; /* bottom scroll limit */ - int mode; /* terminal mode flags */ - int esc; /* escape state flags */ - char trantbl[4]; /* charset table translation */ - int charset; /* current charset */ - int icharset; /* selected charset for sequence */ - int *tabs; - Rune lastc; /* last printed char outside of sequence, 0 if control */ -} Term; - -/* CSI Escape sequence structs */ -/* ESC '[' [[ [] [;]] []] */ -typedef struct { - char buf[ESC_BUF_SIZ]; /* raw string */ - size_t len; /* raw string length */ - char priv; - int arg[ESC_ARG_SIZ]; - int narg; /* nb of args */ - char mode[2]; -} CSIEscape; - -/* STR Escape sequence structs */ -/* ESC type [[ [] [;]] ] ESC '\' */ -typedef struct { - char type; /* ESC type ... */ - char *buf; /* allocated raw string */ - size_t siz; /* allocation size */ - size_t len; /* raw string length */ - char *args[STR_ARG_SIZ]; - int narg; /* nb of args */ -} STREscape; - -static void execsh(char *, char **); -static void stty(char **); -static void sigchld(int); -static void ttywriteraw(const char *, size_t); - -static void csidump(void); -static void csihandle(void); -static void csiparse(void); -static void csireset(void); -static int eschandle(uchar); -static void strdump(void); -static void strhandle(void); -static void strparse(void); -static void strreset(void); - -static void tprinter(char *, size_t); -static void tdumpsel(void); -static void tdumpline(int); -static void tdump(void); -static void tclearregion(int, int, int, int); -static void tcursor(int); -static void tdeletechar(int); -static void tdeleteline(int); -static void tinsertblank(int); -static void tinsertblankline(int); -static int tlinelen(int); -static void tmoveto(int, int); -static void tmoveato(int, int); -static void tnewline(int); -static void tputtab(int); -static void tputc(Rune); -static void treset(void); -static void tscrollup(int, int); -static void tscrolldown(int, int); -static void tsetattr(int *, int); -static void tsetchar(Rune, Glyph *, int, int); -static void tsetdirt(int, int); -static void tsetscroll(int, int); -static void tswapscreen(void); -static void tsetmode(int, int, int *, int); -static int twrite(const char *, int, int); -static void tfulldirt(void); -static void tcontrolcode(uchar ); -static void tdectest(char ); -static void tdefutf8(char); -static int32_t tdefcolor(int *, int *, int); -static void tdeftran(char); -static void tstrsequence(uchar); - -static void drawregion(int, int, int, int); - -static void selnormalize(void); -static void selscroll(int, int); -static void selsnap(int *, int *, int); - -static size_t utf8decode(const char *, Rune *, size_t); -static Rune utf8decodebyte(char, size_t *); -static char utf8encodebyte(Rune, size_t); -static size_t utf8validate(Rune *, size_t); - -static char *base64dec(const char *); -static char base64dec_getc(const char **); - -static ssize_t xwrite(int, const char *, size_t); - -/* Globals */ -static Term term; -static Selection sel; -static CSIEscape csiescseq; -static STREscape strescseq; -static int iofd = 1; -static int cmdfd; -static pid_t pid; - -static uchar utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; -static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; -static Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; -static Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; - -ssize_t -xwrite(int fd, const char *s, size_t len) -{ - size_t aux = len; - ssize_t r; - - while (len > 0) { - r = write(fd, s, len); - if (r < 0) - return r; - len -= r; - s += r; - } - - return aux; -} - -void * -xmalloc(size_t len) -{ - void *p; - - if (!(p = malloc(len))) - die("malloc: %s\n", strerror(errno)); - - return p; -} - -void * -xrealloc(void *p, size_t len) -{ - if ((p = realloc(p, len)) == NULL) - die("realloc: %s\n", strerror(errno)); - - return p; -} - -char * -xstrdup(char *s) -{ - if ((s = strdup(s)) == NULL) - die("strdup: %s\n", strerror(errno)); - - return s; -} - -size_t -utf8decode(const char *c, Rune *u, size_t clen) -{ - size_t i, j, len, type; - Rune 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 != 0) - return j; - } - if (j < len) - return 0; - *u = udecoded; - utf8validate(u, len); - - return len; -} - -Rune -utf8decodebyte(char c, size_t *i) -{ - for (*i = 0; *i < LEN(utfmask); ++(*i)) - if (((uchar)c & utfmask[*i]) == utfbyte[*i]) - return (uchar)c & ~utfmask[*i]; - - return 0; -} - -size_t -utf8encode(Rune u, char *c) -{ - size_t len, i; - - len = utf8validate(&u, 0); - if (len > UTF_SIZ) - return 0; - - for (i = len - 1; i != 0; --i) { - c[i] = utf8encodebyte(u, 0); - u >>= 6; - } - c[0] = utf8encodebyte(u, len); - - return len; -} - -char -utf8encodebyte(Rune u, size_t i) -{ - return utfbyte[i] | (u & ~utfmask[i]); -} - -size_t -utf8validate(Rune *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 const char base64_digits[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, - 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, -1, 0, 0, 0, 0, 1, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -char -base64dec_getc(const char **src) -{ - while (**src && !isprint(**src)) - (*src)++; - return **src ? *((*src)++) : '='; /* emulate padding if string ends */ -} - -char * -base64dec(const char *src) -{ - size_t in_len = strlen(src); - char *result, *dst; - - if (in_len % 4) - in_len += 4 - (in_len % 4); - result = dst = xmalloc(in_len / 4 * 3 + 1); - while (*src) { - int a = base64_digits[(unsigned char) base64dec_getc(&src)]; - int b = base64_digits[(unsigned char) base64dec_getc(&src)]; - int c = base64_digits[(unsigned char) base64dec_getc(&src)]; - int d = base64_digits[(unsigned char) base64dec_getc(&src)]; - - /* invalid input. 'a' can be -1, e.g. if src is "\n" (c-str) */ - if (a == -1 || b == -1) - break; - - *dst++ = (a << 2) | ((b & 0x30) >> 4); - if (c == -1) - break; - *dst++ = ((b & 0x0f) << 4) | ((c & 0x3c) >> 2); - if (d == -1) - break; - *dst++ = ((c & 0x03) << 6) | d; - } - *dst = '\0'; - return result; -} - -void -selinit(void) -{ - sel.mode = SEL_IDLE; - sel.snap = 0; - sel.ob.x = -1; -} - -int -tlinelen(int y) -{ - int i = term.col; - - if (term.line[y][i - 1].mode & ATTR_WRAP) - return i; - - while (i > 0 && term.line[y][i - 1].u == ' ') - --i; - - return i; -} - -void -selstart(int col, int row, int snap) -{ - selclear(); - sel.mode = SEL_EMPTY; - sel.type = SEL_REGULAR; - sel.alt = IS_SET(MODE_ALTSCREEN); - sel.snap = snap; - sel.oe.x = sel.ob.x = col; - sel.oe.y = sel.ob.y = row; - selnormalize(); - - if (sel.snap != 0) - sel.mode = SEL_READY; - tsetdirt(sel.nb.y, sel.ne.y); -} - -void -selextend(int col, int row, int type, int done) -{ - int oldey, oldex, oldsby, oldsey, oldtype; - - if (sel.mode == SEL_IDLE) - return; - if (done && sel.mode == SEL_EMPTY) { - selclear(); - return; - } - - oldey = sel.oe.y; - oldex = sel.oe.x; - oldsby = sel.nb.y; - oldsey = sel.ne.y; - oldtype = sel.type; - - sel.oe.x = col; - sel.oe.y = row; - selnormalize(); - sel.type = type; - - if (oldey != sel.oe.y || oldex != sel.oe.x || oldtype != sel.type || sel.mode == SEL_EMPTY) - tsetdirt(MIN(sel.nb.y, oldsby), MAX(sel.ne.y, oldsey)); - - sel.mode = done ? SEL_IDLE : SEL_READY; -} - -void -selnormalize(void) -{ - int i; - - if (sel.type == SEL_REGULAR && sel.ob.y != sel.oe.y) { - sel.nb.x = sel.ob.y < sel.oe.y ? sel.ob.x : sel.oe.x; - sel.ne.x = sel.ob.y < sel.oe.y ? sel.oe.x : sel.ob.x; - } else { - sel.nb.x = MIN(sel.ob.x, sel.oe.x); - sel.ne.x = MAX(sel.ob.x, sel.oe.x); - } - sel.nb.y = MIN(sel.ob.y, sel.oe.y); - sel.ne.y = MAX(sel.ob.y, sel.oe.y); - - selsnap(&sel.nb.x, &sel.nb.y, -1); - selsnap(&sel.ne.x, &sel.ne.y, +1); - - /* expand selection over line breaks */ - if (sel.type == SEL_RECTANGULAR) - return; - i = tlinelen(sel.nb.y); - if (i < sel.nb.x) - sel.nb.x = i; - if (tlinelen(sel.ne.y) <= sel.ne.x) - sel.ne.x = term.col - 1; -} - -int -selected(int x, int y) -{ - if (sel.mode == SEL_EMPTY || sel.ob.x == -1 || - sel.alt != IS_SET(MODE_ALTSCREEN)) - return 0; - - if (sel.type == SEL_RECTANGULAR) - return BETWEEN(y, sel.nb.y, sel.ne.y) - && BETWEEN(x, sel.nb.x, sel.ne.x); - - return BETWEEN(y, sel.nb.y, sel.ne.y) - && (y != sel.nb.y || x >= sel.nb.x) - && (y != sel.ne.y || x <= sel.ne.x); -} - -void -selsnap(int *x, int *y, int direction) -{ - int newx, newy, xt, yt; - int delim, prevdelim; - Glyph *gp, *prevgp; - - switch (sel.snap) { - case SNAP_WORD: - /* - * Snap around if the word wraps around at the end or - * beginning of a line. - */ - prevgp = &term.line[*y][*x]; - prevdelim = ISDELIM(prevgp->u); - for (;;) { - newx = *x + direction; - newy = *y; - if (!BETWEEN(newx, 0, term.col - 1)) { - newy += direction; - newx = (newx + term.col) % term.col; - if (!BETWEEN(newy, 0, term.row - 1)) - break; - - if (direction > 0) - yt = *y, xt = *x; - else - yt = newy, xt = newx; - if (!(term.line[yt][xt].mode & ATTR_WRAP)) - break; - } - - if (newx >= tlinelen(newy)) - break; - - gp = &term.line[newy][newx]; - delim = ISDELIM(gp->u); - if (!(gp->mode & ATTR_WDUMMY) && (delim != prevdelim - || (delim && gp->u != prevgp->u))) - break; - - *x = newx; - *y = newy; - prevgp = gp; - prevdelim = delim; - } - break; - case SNAP_LINE: - /* - * Snap around if the the previous line or the current one - * has set ATTR_WRAP at its end. Then the whole next or - * previous line will be selected. - */ - *x = (direction < 0) ? 0 : term.col - 1; - if (direction < 0) { - for (; *y > 0; *y += direction) { - if (!(term.line[*y-1][term.col-1].mode - & ATTR_WRAP)) { - break; - } - } - } else if (direction > 0) { - for (; *y < term.row-1; *y += direction) { - if (!(term.line[*y][term.col-1].mode - & ATTR_WRAP)) { - break; - } - } - } - break; - } -} - -char * -getsel(void) -{ - char *str, *ptr; - int y, bufsize, lastx, linelen; - Glyph *gp, *last; - - if (sel.ob.x == -1) - return NULL; - - bufsize = (term.col+1) * (sel.ne.y-sel.nb.y+1) * UTF_SIZ; - ptr = str = xmalloc(bufsize); - - /* append every set & selected glyph to the selection */ - for (y = sel.nb.y; y <= sel.ne.y; y++) { - if ((linelen = tlinelen(y)) == 0) { - *ptr++ = '\n'; - continue; - } - - if (sel.type == SEL_RECTANGULAR) { - gp = &term.line[y][sel.nb.x]; - lastx = sel.ne.x; - } else { - gp = &term.line[y][sel.nb.y == y ? sel.nb.x : 0]; - lastx = (sel.ne.y == y) ? sel.ne.x : term.col-1; - } - last = &term.line[y][MIN(lastx, linelen-1)]; - while (last >= gp && last->u == ' ') - --last; - - for ( ; gp <= last; ++gp) { - if (gp->mode & ATTR_WDUMMY) - continue; - - ptr += utf8encode(gp->u, ptr); - } - - /* - * Copy and pasting of line endings is inconsistent - * in the inconsistent terminal and GUI world. - * The best solution seems like to produce '\n' when - * something is copied from st and convert '\n' to - * '\r', when something to be pasted is received by - * st. - * FIXME: Fix the computer world. - */ - if ((y < sel.ne.y || lastx >= linelen) && - (!(last->mode & ATTR_WRAP) || sel.type == SEL_RECTANGULAR)) - *ptr++ = '\n'; - } - *ptr = 0; - return str; -} - -void -selclear(void) -{ - if (sel.ob.x == -1) - return; - sel.mode = SEL_IDLE; - sel.ob.x = -1; - tsetdirt(sel.nb.y, sel.ne.y); -} - -void -die(const char *errstr, ...) -{ - va_list ap; - - va_start(ap, errstr); - vfprintf(stderr, errstr, ap); - va_end(ap); - exit(1); -} - -void -execsh(char *cmd, char **args) -{ - char *sh, *prog, *arg; - const struct passwd *pw; - - errno = 0; - if ((pw = getpwuid(getuid())) == NULL) { - if (errno) - die("getpwuid: %s\n", strerror(errno)); - else - die("who are you?\n"); - } - - if ((sh = getenv("SHELL")) == NULL) - sh = (pw->pw_shell[0]) ? pw->pw_shell : cmd; - - if (args) { - prog = args[0]; - arg = NULL; - } else if (scroll) { - prog = scroll; - arg = utmp ? utmp : sh; - } else if (utmp) { - prog = utmp; - arg = NULL; - } else { - prog = sh; - arg = NULL; - } - DEFAULT(args, ((char *[]) {prog, arg, NULL})); - - unsetenv("COLUMNS"); - unsetenv("LINES"); - unsetenv("TERMCAP"); - setenv("LOGNAME", pw->pw_name, 1); - setenv("USER", pw->pw_name, 1); - setenv("SHELL", sh, 1); - setenv("HOME", pw->pw_dir, 1); - setenv("TERM", termname, 1); - - signal(SIGCHLD, SIG_DFL); - signal(SIGHUP, SIG_DFL); - signal(SIGINT, SIG_DFL); - signal(SIGQUIT, SIG_DFL); - signal(SIGTERM, SIG_DFL); - signal(SIGALRM, SIG_DFL); - - execvp(prog, args); - _exit(1); -} - -void -sigchld(int a) -{ - int stat; - pid_t p; - - if ((p = waitpid(pid, &stat, WNOHANG)) < 0) - die("waiting for pid %hd failed: %s\n", pid, strerror(errno)); - - if (pid != p) - return; - - if (WIFEXITED(stat) && WEXITSTATUS(stat)) - die("child exited with status %d\n", WEXITSTATUS(stat)); - else if (WIFSIGNALED(stat)) - die("child terminated due to signal %d\n", WTERMSIG(stat)); - _exit(0); -} - -void -stty(char **args) -{ - char cmd[_POSIX_ARG_MAX], **p, *q, *s; - size_t n, siz; - - if ((n = strlen(stty_args)) > sizeof(cmd)-1) - die("incorrect stty parameters\n"); - memcpy(cmd, stty_args, n); - q = cmd + n; - siz = sizeof(cmd) - n; - for (p = args; p && (s = *p); ++p) { - if ((n = strlen(s)) > siz-1) - die("stty parameter length too long\n"); - *q++ = ' '; - memcpy(q, s, n); - q += n; - siz -= n + 1; - } - *q = '\0'; - if (system(cmd) != 0) - perror("Couldn't call stty"); -} - -int -ttynew(char *line, char *cmd, char *out, char **args) -{ - int m, s; - - if (out) { - term.mode |= MODE_PRINT; - iofd = (!strcmp(out, "-")) ? - 1 : open(out, O_WRONLY | O_CREAT, 0666); - if (iofd < 0) { - fprintf(stderr, "Error opening %s:%s\n", - out, strerror(errno)); - } - } - - if (line) { - if ((cmdfd = open(line, O_RDWR)) < 0) - die("open line '%s' failed: %s\n", - line, strerror(errno)); - dup2(cmdfd, 0); - stty(args); - return cmdfd; - } - - /* seems to work fine on linux, openbsd and freebsd */ - if (openpty(&m, &s, NULL, NULL, NULL) < 0) - die("openpty failed: %s\n", strerror(errno)); - - switch (pid = fork()) { - case -1: - die("fork failed: %s\n", strerror(errno)); - break; - case 0: - close(iofd); - setsid(); /* create a new process group */ - dup2(s, 0); - dup2(s, 1); - dup2(s, 2); - if (ioctl(s, TIOCSCTTY, NULL) < 0) - die("ioctl TIOCSCTTY failed: %s\n", strerror(errno)); - close(s); - close(m); -#ifdef __OpenBSD__ - if (pledge("stdio getpw proc exec", NULL) == -1) - die("pledge\n"); -#endif - execsh(cmd, args); - break; - default: -#ifdef __OpenBSD__ - if (pledge("stdio rpath tty proc", NULL) == -1) - die("pledge\n"); -#endif - close(s); - cmdfd = m; - signal(SIGCHLD, sigchld); - break; - } - return cmdfd; -} - -size_t -ttyread(void) -{ - static char buf[BUFSIZ]; - static int buflen = 0; - int ret, written; - - /* append read bytes to unprocessed bytes */ - ret = read(cmdfd, buf+buflen, LEN(buf)-buflen); - - switch (ret) { - case 0: - exit(0); - case -1: - die("couldn't read from shell: %s\n", strerror(errno)); - default: - buflen += ret; - written = twrite(buf, buflen, 0); - buflen -= written; - /* keep any incomplete UTF-8 byte sequence for the next call */ - if (buflen > 0) - memmove(buf, buf + written, buflen); - return ret; - } -} - -void -ttywrite(const char *s, size_t n, int may_echo) -{ - const char *next; - - if (may_echo && IS_SET(MODE_ECHO)) - twrite(s, n, 1); - - if (!IS_SET(MODE_CRLF)) { - ttywriteraw(s, n); - return; - } - - /* This is similar to how the kernel handles ONLCR for ttys */ - while (n > 0) { - if (*s == '\r') { - next = s + 1; - ttywriteraw("\r\n", 2); - } else { - next = memchr(s, '\r', n); - DEFAULT(next, s + n); - ttywriteraw(s, next - s); - } - n -= next - s; - s = next; - } -} - -void -ttywriteraw(const char *s, size_t n) -{ - fd_set wfd, rfd; - ssize_t r; - size_t lim = 256; - - /* - * Remember that we are using a pty, which might be a modem line. - * Writing too much will clog the line. That's why we are doing this - * dance. - * FIXME: Migrate the world to Plan 9. - */ - while (n > 0) { - FD_ZERO(&wfd); - FD_ZERO(&rfd); - FD_SET(cmdfd, &wfd); - FD_SET(cmdfd, &rfd); - - /* Check if we can write. */ - if (pselect(cmdfd+1, &rfd, &wfd, NULL, NULL, NULL) < 0) { - if (errno == EINTR) - continue; - die("select failed: %s\n", strerror(errno)); - } - if (FD_ISSET(cmdfd, &wfd)) { - /* - * Only write the bytes written by ttywrite() or the - * default of 256. This seems to be a reasonable value - * for a serial line. Bigger values might clog the I/O. - */ - if ((r = write(cmdfd, s, (n < lim)? n : lim)) < 0) - goto write_error; - if (r < n) { - /* - * We weren't able to write out everything. - * This means the buffer is getting full - * again. Empty it. - */ - if (n < lim) - lim = ttyread(); - n -= r; - s += r; - } else { - /* All bytes have been written. */ - break; - } - } - if (FD_ISSET(cmdfd, &rfd)) - lim = ttyread(); - } - return; - -write_error: - die("write error on tty: %s\n", strerror(errno)); -} - -void -ttyresize(int tw, int th) -{ - struct winsize w; - - w.ws_row = term.row; - w.ws_col = term.col; - w.ws_xpixel = tw; - w.ws_ypixel = th; - if (ioctl(cmdfd, TIOCSWINSZ, &w) < 0) - fprintf(stderr, "Couldn't set window size: %s\n", strerror(errno)); -} - -void -ttyhangup() -{ - /* Send SIGHUP to shell */ - kill(pid, SIGHUP); -} - -int -tattrset(int attr) -{ - int i, j; - - for (i = 0; i < term.row-1; i++) { - for (j = 0; j < term.col-1; j++) { - if (term.line[i][j].mode & attr) - return 1; - } - } - - return 0; -} - -void -tsetdirt(int top, int bot) -{ - int i; - - LIMIT(top, 0, term.row-1); - LIMIT(bot, 0, term.row-1); - - for (i = top; i <= bot; i++) - term.dirty[i] = 1; -} - -void -tsetdirtattr(int attr) -{ - int i, j; - - for (i = 0; i < term.row-1; i++) { - for (j = 0; j < term.col-1; j++) { - if (term.line[i][j].mode & attr) { - tsetdirt(i, i); - break; - } - } - } -} - -void -tfulldirt(void) -{ - tsetdirt(0, term.row-1); -} - -void -tcursor(int mode) -{ - static TCursor c[2]; - int alt = IS_SET(MODE_ALTSCREEN); - - if (mode == CURSOR_SAVE) { - c[alt] = term.c; - } else if (mode == CURSOR_LOAD) { - term.c = c[alt]; - tmoveto(c[alt].x, c[alt].y); - } -} - -void -treset(void) -{ - uint i; - - term.c = (TCursor){{ - .mode = ATTR_NULL, - .fg = defaultfg, - .bg = defaultbg - }, .x = 0, .y = 0, .state = CURSOR_DEFAULT}; - - memset(term.tabs, 0, term.col * sizeof(*term.tabs)); - for (i = tabspaces; i < term.col; i += tabspaces) - term.tabs[i] = 1; - term.top = 0; - term.bot = term.row - 1; - term.mode = MODE_WRAP|MODE_UTF8; - memset(term.trantbl, CS_USA, sizeof(term.trantbl)); - term.charset = 0; - - for (i = 0; i < 2; i++) { - tmoveto(0, 0); - tcursor(CURSOR_SAVE); - tclearregion(0, 0, term.col-1, term.row-1); - tswapscreen(); - } -} - -void -tnew(int col, int row) -{ - term = (Term){ .c = { .attr = { .fg = defaultfg, .bg = defaultbg } } }; - tresize(col, row); - treset(); -} - -void -tswapscreen(void) -{ - Line *tmp = term.line; - - term.line = term.alt; - term.alt = tmp; - term.mode ^= MODE_ALTSCREEN; - tfulldirt(); -} - -void -tscrolldown(int orig, int n) -{ - int i; - Line temp; - - LIMIT(n, 0, term.bot-orig+1); - - tsetdirt(orig, term.bot-n); - tclearregion(0, term.bot-n+1, term.col-1, term.bot); - - for (i = term.bot; i >= orig+n; i--) { - temp = term.line[i]; - term.line[i] = term.line[i-n]; - term.line[i-n] = temp; - } - - selscroll(orig, n); -} - -void -tscrollup(int orig, int n) -{ - int i; - Line temp; - - LIMIT(n, 0, term.bot-orig+1); - - tclearregion(0, orig, term.col-1, orig+n-1); - tsetdirt(orig+n, term.bot); - - for (i = orig; i <= term.bot-n; i++) { - temp = term.line[i]; - term.line[i] = term.line[i+n]; - term.line[i+n] = temp; - } - - selscroll(orig, -n); -} - -void -selscroll(int orig, int n) -{ - if (sel.ob.x == -1) - return; - - if (BETWEEN(sel.nb.y, orig, term.bot) != BETWEEN(sel.ne.y, orig, term.bot)) { - selclear(); - } else if (BETWEEN(sel.nb.y, orig, term.bot)) { - sel.ob.y += n; - sel.oe.y += n; - if (sel.ob.y < term.top || sel.ob.y > term.bot || - sel.oe.y < term.top || sel.oe.y > term.bot) { - selclear(); - } else { - selnormalize(); - } - } -} - -void -tnewline(int first_col) -{ - int y = term.c.y; - - if (y == term.bot) { - tscrollup(term.top, 1); - } else { - y++; - } - tmoveto(first_col ? 0 : term.c.x, y); -} - -void -csiparse(void) -{ - char *p = csiescseq.buf, *np; - long int v; - - csiescseq.narg = 0; - if (*p == '?') { - csiescseq.priv = 1; - p++; - } - - csiescseq.buf[csiescseq.len] = '\0'; - while (p < csiescseq.buf+csiescseq.len) { - np = NULL; - v = strtol(p, &np, 10); - if (np == p) - v = 0; - if (v == LONG_MAX || v == LONG_MIN) - v = -1; - csiescseq.arg[csiescseq.narg++] = v; - p = np; - if (*p != ';' || csiescseq.narg == ESC_ARG_SIZ) - break; - p++; - } - csiescseq.mode[0] = *p++; - csiescseq.mode[1] = (p < csiescseq.buf+csiescseq.len) ? *p : '\0'; -} - -/* for absolute user moves, when decom is set */ -void -tmoveato(int x, int y) -{ - tmoveto(x, y + ((term.c.state & CURSOR_ORIGIN) ? term.top: 0)); -} - -void -tmoveto(int x, int y) -{ - int miny, maxy; - - if (term.c.state & CURSOR_ORIGIN) { - miny = term.top; - maxy = term.bot; - } else { - miny = 0; - maxy = term.row - 1; - } - term.c.state &= ~CURSOR_WRAPNEXT; - term.c.x = LIMIT(x, 0, term.col-1); - term.c.y = LIMIT(y, miny, maxy); -} - -void -tsetchar(Rune u, Glyph *attr, int x, int y) -{ - static char *vt100_0[62] = { /* 0x41 - 0x7e */ - "↑", "↓", "→", "←", "█", "▚", "☃", /* A - G */ - 0, 0, 0, 0, 0, 0, 0, 0, /* H - O */ - 0, 0, 0, 0, 0, 0, 0, 0, /* P - W */ - 0, 0, 0, 0, 0, 0, 0, " ", /* X - _ */ - "◆", "▒", "␉", "␌", "␍", "␊", "°", "±", /* ` - g */ - "␤", "␋", "┘", "┐", "┌", "└", "┼", "⎺", /* h - o */ - "⎻", "─", "⎼", "⎽", "├", "┤", "┴", "┬", /* p - w */ - "│", "≤", "≥", "π", "≠", "£", "·", /* x - ~ */ - }; - - /* - * The table is proudly stolen from rxvt. - */ - if (term.trantbl[term.charset] == CS_GRAPHIC0 && - BETWEEN(u, 0x41, 0x7e) && vt100_0[u - 0x41]) - utf8decode(vt100_0[u - 0x41], &u, UTF_SIZ); - - if (term.line[y][x].mode & ATTR_WIDE) { - if (x+1 < term.col) { - term.line[y][x+1].u = ' '; - term.line[y][x+1].mode &= ~ATTR_WDUMMY; - } - } else if (term.line[y][x].mode & ATTR_WDUMMY) { - term.line[y][x-1].u = ' '; - term.line[y][x-1].mode &= ~ATTR_WIDE; - } - - term.dirty[y] = 1; - term.line[y][x] = *attr; - term.line[y][x].u = u; -} - -void -tclearregion(int x1, int y1, int x2, int y2) -{ - int x, y, temp; - Glyph *gp; - - if (x1 > x2) - temp = x1, x1 = x2, x2 = temp; - if (y1 > y2) - temp = y1, y1 = y2, y2 = temp; - - LIMIT(x1, 0, term.col-1); - LIMIT(x2, 0, term.col-1); - LIMIT(y1, 0, term.row-1); - LIMIT(y2, 0, term.row-1); - - for (y = y1; y <= y2; y++) { - term.dirty[y] = 1; - for (x = x1; x <= x2; x++) { - gp = &term.line[y][x]; - if (selected(x, y)) - selclear(); - gp->fg = term.c.attr.fg; - gp->bg = term.c.attr.bg; - gp->mode = 0; - gp->u = ' '; - } - } -} - -void -tdeletechar(int n) -{ - int dst, src, size; - Glyph *line; - - LIMIT(n, 0, term.col - term.c.x); - - dst = term.c.x; - src = term.c.x + n; - size = term.col - src; - line = term.line[term.c.y]; - - memmove(&line[dst], &line[src], size * sizeof(Glyph)); - tclearregion(term.col-n, term.c.y, term.col-1, term.c.y); -} - -void -tinsertblank(int n) -{ - int dst, src, size; - Glyph *line; - - LIMIT(n, 0, term.col - term.c.x); - - dst = term.c.x + n; - src = term.c.x; - size = term.col - dst; - line = term.line[term.c.y]; - - memmove(&line[dst], &line[src], size * sizeof(Glyph)); - tclearregion(src, term.c.y, dst - 1, term.c.y); -} - -void -tinsertblankline(int n) -{ - if (BETWEEN(term.c.y, term.top, term.bot)) - tscrolldown(term.c.y, n); -} - -void -tdeleteline(int n) -{ - if (BETWEEN(term.c.y, term.top, term.bot)) - tscrollup(term.c.y, n); -} - -int32_t -tdefcolor(int *attr, int *npar, int l) -{ - int32_t idx = -1; - uint r, g, b; - - switch (attr[*npar + 1]) { - case 2: /* direct color in RGB space */ - if (*npar + 4 >= l) { - fprintf(stderr, - "erresc(38): Incorrect number of parameters (%d)\n", - *npar); - break; - } - r = attr[*npar + 2]; - g = attr[*npar + 3]; - b = attr[*npar + 4]; - *npar += 4; - if (!BETWEEN(r, 0, 255) || !BETWEEN(g, 0, 255) || !BETWEEN(b, 0, 255)) - fprintf(stderr, "erresc: bad rgb color (%u,%u,%u)\n", - r, g, b); - else - idx = TRUECOLOR(r, g, b); - break; - case 5: /* indexed color */ - if (*npar + 2 >= l) { - fprintf(stderr, - "erresc(38): Incorrect number of parameters (%d)\n", - *npar); - break; - } - *npar += 2; - if (!BETWEEN(attr[*npar], 0, 255)) - fprintf(stderr, "erresc: bad fgcolor %d\n", attr[*npar]); - else - idx = attr[*npar]; - break; - case 0: /* implemented defined (only foreground) */ - case 1: /* transparent */ - case 3: /* direct color in CMY space */ - case 4: /* direct color in CMYK space */ - default: - fprintf(stderr, - "erresc(38): gfx attr %d unknown\n", attr[*npar]); - break; - } - - return idx; -} - -void -tsetattr(int *attr, int l) -{ - int i; - int32_t idx; - - for (i = 0; i < l; i++) { - switch (attr[i]) { - case 0: - term.c.attr.mode &= ~( - ATTR_BOLD | - ATTR_FAINT | - ATTR_ITALIC | - ATTR_UNDERLINE | - ATTR_BLINK | - ATTR_REVERSE | - ATTR_INVISIBLE | - ATTR_STRUCK ); - term.c.attr.fg = defaultfg; - term.c.attr.bg = defaultbg; - break; - case 1: - term.c.attr.mode |= ATTR_BOLD; - break; - case 2: - term.c.attr.mode |= ATTR_FAINT; - break; - case 3: - term.c.attr.mode |= ATTR_ITALIC; - break; - case 4: - term.c.attr.mode |= ATTR_UNDERLINE; - break; - case 5: /* slow blink */ - /* FALLTHROUGH */ - case 6: /* rapid blink */ - term.c.attr.mode |= ATTR_BLINK; - break; - case 7: - term.c.attr.mode |= ATTR_REVERSE; - break; - case 8: - term.c.attr.mode |= ATTR_INVISIBLE; - break; - case 9: - term.c.attr.mode |= ATTR_STRUCK; - break; - case 22: - term.c.attr.mode &= ~(ATTR_BOLD | ATTR_FAINT); - break; - case 23: - term.c.attr.mode &= ~ATTR_ITALIC; - break; - case 24: - term.c.attr.mode &= ~ATTR_UNDERLINE; - break; - case 25: - term.c.attr.mode &= ~ATTR_BLINK; - break; - case 27: - term.c.attr.mode &= ~ATTR_REVERSE; - break; - case 28: - term.c.attr.mode &= ~ATTR_INVISIBLE; - break; - case 29: - term.c.attr.mode &= ~ATTR_STRUCK; - break; - case 38: - if ((idx = tdefcolor(attr, &i, l)) >= 0) - term.c.attr.fg = idx; - break; - case 39: - term.c.attr.fg = defaultfg; - break; - case 48: - if ((idx = tdefcolor(attr, &i, l)) >= 0) - term.c.attr.bg = idx; - break; - case 49: - term.c.attr.bg = defaultbg; - break; - default: - if (BETWEEN(attr[i], 30, 37)) { - term.c.attr.fg = attr[i] - 30; - } else if (BETWEEN(attr[i], 40, 47)) { - term.c.attr.bg = attr[i] - 40; - } else if (BETWEEN(attr[i], 90, 97)) { - term.c.attr.fg = attr[i] - 90 + 8; - } else if (BETWEEN(attr[i], 100, 107)) { - term.c.attr.bg = attr[i] - 100 + 8; - } else { - fprintf(stderr, - "erresc(default): gfx attr %d unknown\n", - attr[i]); - csidump(); - } - break; - } - } -} - -void -tsetscroll(int t, int b) -{ - int temp; - - LIMIT(t, 0, term.row-1); - LIMIT(b, 0, term.row-1); - if (t > b) { - temp = t; - t = b; - b = temp; - } - term.top = t; - term.bot = b; -} - -void -tsetmode(int priv, int set, int *args, int narg) -{ - int alt, *lim; - - for (lim = args + narg; args < lim; ++args) { - if (priv) { - switch (*args) { - case 1: /* DECCKM -- Cursor key */ - xsetmode(set, MODE_APPCURSOR); - break; - case 5: /* DECSCNM -- Reverse video */ - xsetmode(set, MODE_REVERSE); - break; - case 6: /* DECOM -- Origin */ - MODBIT(term.c.state, set, CURSOR_ORIGIN); - tmoveato(0, 0); - break; - case 7: /* DECAWM -- Auto wrap */ - MODBIT(term.mode, set, MODE_WRAP); - break; - case 0: /* Error (IGNORED) */ - case 2: /* DECANM -- ANSI/VT52 (IGNORED) */ - case 3: /* DECCOLM -- Column (IGNORED) */ - case 4: /* DECSCLM -- Scroll (IGNORED) */ - case 8: /* DECARM -- Auto repeat (IGNORED) */ - case 18: /* DECPFF -- Printer feed (IGNORED) */ - case 19: /* DECPEX -- Printer extent (IGNORED) */ - case 42: /* DECNRCM -- National characters (IGNORED) */ - case 12: /* att610 -- Start blinking cursor (IGNORED) */ - break; - case 25: /* DECTCEM -- Text Cursor Enable Mode */ - xsetmode(!set, MODE_HIDE); - break; - case 9: /* X10 mouse compatibility mode */ - xsetpointermotion(0); - xsetmode(0, MODE_MOUSE); - xsetmode(set, MODE_MOUSEX10); - break; - case 1000: /* 1000: report button press */ - xsetpointermotion(0); - xsetmode(0, MODE_MOUSE); - xsetmode(set, MODE_MOUSEBTN); - break; - case 1002: /* 1002: report motion on button press */ - xsetpointermotion(0); - xsetmode(0, MODE_MOUSE); - xsetmode(set, MODE_MOUSEMOTION); - break; - case 1003: /* 1003: enable all mouse motions */ - xsetpointermotion(set); - xsetmode(0, MODE_MOUSE); - xsetmode(set, MODE_MOUSEMANY); - break; - case 1004: /* 1004: send focus events to tty */ - xsetmode(set, MODE_FOCUS); - break; - case 1006: /* 1006: extended reporting mode */ - xsetmode(set, MODE_MOUSESGR); - break; - case 1034: - xsetmode(set, MODE_8BIT); - break; - case 1049: /* swap screen & set/restore cursor as xterm */ - if (!allowaltscreen) - break; - tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD); - /* FALLTHROUGH */ - case 47: /* swap screen */ - case 1047: - if (!allowaltscreen) - break; - alt = IS_SET(MODE_ALTSCREEN); - if (alt) { - tclearregion(0, 0, term.col-1, - term.row-1); - } - if (set ^ alt) /* set is always 1 or 0 */ - tswapscreen(); - if (*args != 1049) - break; - /* FALLTHROUGH */ - case 1048: - tcursor((set) ? CURSOR_SAVE : CURSOR_LOAD); - break; - case 2004: /* 2004: bracketed paste mode */ - xsetmode(set, MODE_BRCKTPASTE); - break; - /* Not implemented mouse modes. See comments there. */ - case 1001: /* mouse highlight mode; can hang the - terminal by design when implemented. */ - case 1005: /* UTF-8 mouse mode; will confuse - applications not supporting UTF-8 - and luit. */ - case 1015: /* urxvt mangled mouse mode; incompatible - and can be mistaken for other control - codes. */ - break; - default: - fprintf(stderr, - "erresc: unknown private set/reset mode %d\n", - *args); - break; - } - } else { - switch (*args) { - case 0: /* Error (IGNORED) */ - break; - case 2: - xsetmode(set, MODE_KBDLOCK); - break; - case 4: /* IRM -- Insertion-replacement */ - MODBIT(term.mode, set, MODE_INSERT); - break; - case 12: /* SRM -- Send/Receive */ - MODBIT(term.mode, !set, MODE_ECHO); - break; - case 20: /* LNM -- Linefeed/new line */ - MODBIT(term.mode, set, MODE_CRLF); - break; - default: - fprintf(stderr, - "erresc: unknown set/reset mode %d\n", - *args); - break; - } - } - } -} - -void -csihandle(void) -{ - char buf[40]; - int len; - - switch (csiescseq.mode[0]) { - default: - unknown: - fprintf(stderr, "erresc: unknown csi "); - csidump(); - /* die(""); */ - break; - case '@': /* ICH -- Insert blank char */ - DEFAULT(csiescseq.arg[0], 1); - tinsertblank(csiescseq.arg[0]); - break; - case 'A': /* CUU -- Cursor Up */ - DEFAULT(csiescseq.arg[0], 1); - tmoveto(term.c.x, term.c.y-csiescseq.arg[0]); - break; - case 'B': /* CUD -- Cursor Down */ - case 'e': /* VPR --Cursor Down */ - DEFAULT(csiescseq.arg[0], 1); - tmoveto(term.c.x, term.c.y+csiescseq.arg[0]); - break; - case 'i': /* MC -- Media Copy */ - switch (csiescseq.arg[0]) { - case 0: - tdump(); - break; - case 1: - tdumpline(term.c.y); - break; - case 2: - tdumpsel(); - break; - case 4: - term.mode &= ~MODE_PRINT; - break; - case 5: - term.mode |= MODE_PRINT; - break; - } - break; - case 'c': /* DA -- Device Attributes */ - if (csiescseq.arg[0] == 0) - ttywrite(vtiden, strlen(vtiden), 0); - break; - case 'b': /* REP -- if last char is printable print it more times */ - DEFAULT(csiescseq.arg[0], 1); - if (term.lastc) - while (csiescseq.arg[0]-- > 0) - tputc(term.lastc); - break; - case 'C': /* CUF -- Cursor Forward */ - case 'a': /* HPR -- Cursor Forward */ - DEFAULT(csiescseq.arg[0], 1); - tmoveto(term.c.x+csiescseq.arg[0], term.c.y); - break; - case 'D': /* CUB -- Cursor Backward */ - DEFAULT(csiescseq.arg[0], 1); - tmoveto(term.c.x-csiescseq.arg[0], term.c.y); - break; - case 'E': /* CNL -- Cursor Down and first col */ - DEFAULT(csiescseq.arg[0], 1); - tmoveto(0, term.c.y+csiescseq.arg[0]); - break; - case 'F': /* CPL -- Cursor Up and first col */ - DEFAULT(csiescseq.arg[0], 1); - tmoveto(0, term.c.y-csiescseq.arg[0]); - break; - case 'g': /* TBC -- Tabulation clear */ - switch (csiescseq.arg[0]) { - case 0: /* clear current tab stop */ - term.tabs[term.c.x] = 0; - break; - case 3: /* clear all the tabs */ - memset(term.tabs, 0, term.col * sizeof(*term.tabs)); - break; - default: - goto unknown; - } - break; - case 'G': /* CHA -- Move to */ - case '`': /* HPA */ - DEFAULT(csiescseq.arg[0], 1); - tmoveto(csiescseq.arg[0]-1, term.c.y); - break; - case 'H': /* CUP -- Move to */ - case 'f': /* HVP */ - DEFAULT(csiescseq.arg[0], 1); - DEFAULT(csiescseq.arg[1], 1); - tmoveato(csiescseq.arg[1]-1, csiescseq.arg[0]-1); - break; - case 'I': /* CHT -- Cursor Forward Tabulation tab stops */ - DEFAULT(csiescseq.arg[0], 1); - tputtab(csiescseq.arg[0]); - break; - case 'J': /* ED -- Clear screen */ - switch (csiescseq.arg[0]) { - case 0: /* below */ - tclearregion(term.c.x, term.c.y, term.col-1, term.c.y); - if (term.c.y < term.row-1) { - tclearregion(0, term.c.y+1, term.col-1, - term.row-1); - } - break; - case 1: /* above */ - if (term.c.y > 1) - tclearregion(0, 0, term.col-1, term.c.y-1); - tclearregion(0, term.c.y, term.c.x, term.c.y); - break; - case 2: /* all */ - tclearregion(0, 0, term.col-1, term.row-1); - break; - default: - goto unknown; - } - break; - case 'K': /* EL -- Clear line */ - switch (csiescseq.arg[0]) { - case 0: /* right */ - tclearregion(term.c.x, term.c.y, term.col-1, - term.c.y); - break; - case 1: /* left */ - tclearregion(0, term.c.y, term.c.x, term.c.y); - break; - case 2: /* all */ - tclearregion(0, term.c.y, term.col-1, term.c.y); - break; - } - break; - case 'S': /* SU -- Scroll line up */ - DEFAULT(csiescseq.arg[0], 1); - tscrollup(term.top, csiescseq.arg[0]); - break; - case 'T': /* SD -- Scroll line down */ - DEFAULT(csiescseq.arg[0], 1); - tscrolldown(term.top, csiescseq.arg[0]); - break; - case 'L': /* IL -- Insert blank lines */ - DEFAULT(csiescseq.arg[0], 1); - tinsertblankline(csiescseq.arg[0]); - break; - case 'l': /* RM -- Reset Mode */ - tsetmode(csiescseq.priv, 0, csiescseq.arg, csiescseq.narg); - break; - case 'M': /* DL -- Delete lines */ - DEFAULT(csiescseq.arg[0], 1); - tdeleteline(csiescseq.arg[0]); - break; - case 'X': /* ECH -- Erase char */ - DEFAULT(csiescseq.arg[0], 1); - tclearregion(term.c.x, term.c.y, - term.c.x + csiescseq.arg[0] - 1, term.c.y); - break; - case 'P': /* DCH -- Delete char */ - DEFAULT(csiescseq.arg[0], 1); - tdeletechar(csiescseq.arg[0]); - break; - case 'Z': /* CBT -- Cursor Backward Tabulation tab stops */ - DEFAULT(csiescseq.arg[0], 1); - tputtab(-csiescseq.arg[0]); - break; - case 'd': /* VPA -- Move to */ - DEFAULT(csiescseq.arg[0], 1); - tmoveato(term.c.x, csiescseq.arg[0]-1); - break; - case 'h': /* SM -- Set terminal mode */ - tsetmode(csiescseq.priv, 1, csiescseq.arg, csiescseq.narg); - break; - case 'm': /* SGR -- Terminal attribute (color) */ - tsetattr(csiescseq.arg, csiescseq.narg); - break; - case 'n': /* DSR – Device Status Report (cursor position) */ - if (csiescseq.arg[0] == 6) { - len = snprintf(buf, sizeof(buf), "\033[%i;%iR", - term.c.y+1, term.c.x+1); - ttywrite(buf, len, 0); - } - break; - case 'r': /* DECSTBM -- Set Scrolling Region */ - if (csiescseq.priv) { - goto unknown; - } else { - DEFAULT(csiescseq.arg[0], 1); - DEFAULT(csiescseq.arg[1], term.row); - tsetscroll(csiescseq.arg[0]-1, csiescseq.arg[1]-1); - tmoveato(0, 0); - } - break; - case 's': /* DECSC -- Save cursor position (ANSI.SYS) */ - tcursor(CURSOR_SAVE); - break; - case 'u': /* DECRC -- Restore cursor position (ANSI.SYS) */ - tcursor(CURSOR_LOAD); - break; - case ' ': - switch (csiescseq.mode[1]) { - case 'q': /* DECSCUSR -- Set Cursor Style */ - if (xsetcursor(csiescseq.arg[0])) - goto unknown; - break; - default: - goto unknown; - } - break; - } -} - -void -csidump(void) -{ - size_t i; - uint c; - - fprintf(stderr, "ESC["); - for (i = 0; i < csiescseq.len; i++) { - c = csiescseq.buf[i] & 0xff; - if (isprint(c)) { - putc(c, stderr); - } else if (c == '\n') { - fprintf(stderr, "(\\n)"); - } else if (c == '\r') { - fprintf(stderr, "(\\r)"); - } else if (c == 0x1b) { - fprintf(stderr, "(\\e)"); - } else { - fprintf(stderr, "(%02x)", c); - } - } - putc('\n', stderr); -} - -void -csireset(void) -{ - memset(&csiescseq, 0, sizeof(csiescseq)); -} - -void -strhandle(void) -{ - char *p = NULL, *dec; - int j, narg, par; - - term.esc &= ~(ESC_STR_END|ESC_STR); - strparse(); - par = (narg = strescseq.narg) ? atoi(strescseq.args[0]) : 0; - - switch (strescseq.type) { - case ']': /* OSC -- Operating System Command */ - switch (par) { - case 0: - if (narg > 1) { - xsettitle(strescseq.args[1]); - xseticontitle(strescseq.args[1]); - } - return; - case 1: - if (narg > 1) - xseticontitle(strescseq.args[1]); - return; - case 2: - if (narg > 1) - xsettitle(strescseq.args[1]); - return; - case 52: - if (narg > 2 && allowwindowops) { - dec = base64dec(strescseq.args[2]); - if (dec) { - xsetsel(dec); - xclipcopy(); - } else { - fprintf(stderr, "erresc: invalid base64\n"); - } - } - return; - case 4: /* color set */ - if (narg < 3) - break; - p = strescseq.args[2]; - /* FALLTHROUGH */ - case 104: /* color reset, here p = NULL */ - j = (narg > 1) ? atoi(strescseq.args[1]) : -1; - if (xsetcolorname(j, p)) { - if (par == 104 && narg <= 1) - return; /* color reset without parameter */ - fprintf(stderr, "erresc: invalid color j=%d, p=%s\n", - j, p ? p : "(null)"); - } else { - /* - * TODO if defaultbg color is changed, borders - * are dirty - */ - redraw(); - } - return; - } - break; - case 'k': /* old title set compatibility */ - xsettitle(strescseq.args[0]); - return; - case 'P': /* DCS -- Device Control String */ - case '_': /* APC -- Application Program Command */ - case '^': /* PM -- Privacy Message */ - return; - } - - fprintf(stderr, "erresc: unknown str "); - strdump(); -} - -void -strparse(void) -{ - int c; - char *p = strescseq.buf; - - strescseq.narg = 0; - strescseq.buf[strescseq.len] = '\0'; - - if (*p == '\0') - return; - - while (strescseq.narg < STR_ARG_SIZ) { - strescseq.args[strescseq.narg++] = p; - while ((c = *p) != ';' && c != '\0') - ++p; - if (c == '\0') - return; - *p++ = '\0'; - } -} - -void -strdump(void) -{ - size_t i; - uint c; - - fprintf(stderr, "ESC%c", strescseq.type); - for (i = 0; i < strescseq.len; i++) { - c = strescseq.buf[i] & 0xff; - if (c == '\0') { - putc('\n', stderr); - return; - } else if (isprint(c)) { - putc(c, stderr); - } else if (c == '\n') { - fprintf(stderr, "(\\n)"); - } else if (c == '\r') { - fprintf(stderr, "(\\r)"); - } else if (c == 0x1b) { - fprintf(stderr, "(\\e)"); - } else { - fprintf(stderr, "(%02x)", c); - } - } - fprintf(stderr, "ESC\\\n"); -} - -void -strreset(void) -{ - strescseq = (STREscape){ - .buf = xrealloc(strescseq.buf, STR_BUF_SIZ), - .siz = STR_BUF_SIZ, - }; -} - -void -sendbreak(const Arg *arg) -{ - if (tcsendbreak(cmdfd, 0)) - perror("Error sending break"); -} - -void -tprinter(char *s, size_t len) -{ - if (iofd != -1 && xwrite(iofd, s, len) < 0) { - perror("Error writing to output file"); - close(iofd); - iofd = -1; - } -} - -void -toggleprinter(const Arg *arg) -{ - term.mode ^= MODE_PRINT; -} - -void -printscreen(const Arg *arg) -{ - tdump(); -} - -void -printsel(const Arg *arg) -{ - tdumpsel(); -} - -void -tdumpsel(void) -{ - char *ptr; - - if ((ptr = getsel())) { - tprinter(ptr, strlen(ptr)); - free(ptr); - } -} - -void -tdumpline(int n) -{ - char buf[UTF_SIZ]; - Glyph *bp, *end; - - bp = &term.line[n][0]; - end = &bp[MIN(tlinelen(n), term.col) - 1]; - if (bp != end || bp->u != ' ') { - for ( ; bp <= end; ++bp) - tprinter(buf, utf8encode(bp->u, buf)); - } - tprinter("\n", 1); -} - -void -tdump(void) -{ - int i; - - for (i = 0; i < term.row; ++i) - tdumpline(i); -} - -void -tputtab(int n) -{ - uint x = term.c.x; - - if (n > 0) { - while (x < term.col && n--) - for (++x; x < term.col && !term.tabs[x]; ++x) - /* nothing */ ; - } else if (n < 0) { - while (x > 0 && n++) - for (--x; x > 0 && !term.tabs[x]; --x) - /* nothing */ ; - } - term.c.x = LIMIT(x, 0, term.col-1); -} - -void -tdefutf8(char ascii) -{ - if (ascii == 'G') - term.mode |= MODE_UTF8; - else if (ascii == '@') - term.mode &= ~MODE_UTF8; -} - -void -tdeftran(char ascii) -{ - static char cs[] = "0B"; - static int vcs[] = {CS_GRAPHIC0, CS_USA}; - char *p; - - if ((p = strchr(cs, ascii)) == NULL) { - fprintf(stderr, "esc unhandled charset: ESC ( %c\n", ascii); - } else { - term.trantbl[term.icharset] = vcs[p - cs]; - } -} - -void -tdectest(char c) -{ - int x, y; - - if (c == '8') { /* DEC screen alignment test. */ - for (x = 0; x < term.col; ++x) { - for (y = 0; y < term.row; ++y) - tsetchar('E', &term.c.attr, x, y); - } - } -} - -void -tstrsequence(uchar c) -{ - switch (c) { - case 0x90: /* DCS -- Device Control String */ - c = 'P'; - break; - case 0x9f: /* APC -- Application Program Command */ - c = '_'; - break; - case 0x9e: /* PM -- Privacy Message */ - c = '^'; - break; - case 0x9d: /* OSC -- Operating System Command */ - c = ']'; - break; - } - strreset(); - strescseq.type = c; - term.esc |= ESC_STR; -} - -void -tcontrolcode(uchar ascii) -{ - switch (ascii) { - case '\t': /* HT */ - tputtab(1); - return; - case '\b': /* BS */ - tmoveto(term.c.x-1, term.c.y); - return; - case '\r': /* CR */ - tmoveto(0, term.c.y); - return; - case '\f': /* LF */ - case '\v': /* VT */ - case '\n': /* LF */ - /* go to first col if the mode is set */ - tnewline(IS_SET(MODE_CRLF)); - return; - case '\a': /* BEL */ - if (term.esc & ESC_STR_END) { - /* backwards compatibility to xterm */ - strhandle(); - } else { - xbell(); - } - break; - case '\033': /* ESC */ - csireset(); - term.esc &= ~(ESC_CSI|ESC_ALTCHARSET|ESC_TEST); - term.esc |= ESC_START; - return; - case '\016': /* SO (LS1 -- Locking shift 1) */ - case '\017': /* SI (LS0 -- Locking shift 0) */ - term.charset = 1 - (ascii - '\016'); - return; - case '\032': /* SUB */ - tsetchar('?', &term.c.attr, term.c.x, term.c.y); - /* FALLTHROUGH */ - case '\030': /* CAN */ - csireset(); - break; - case '\005': /* ENQ (IGNORED) */ - case '\000': /* NUL (IGNORED) */ - case '\021': /* XON (IGNORED) */ - case '\023': /* XOFF (IGNORED) */ - case 0177: /* DEL (IGNORED) */ - return; - case 0x80: /* TODO: PAD */ - case 0x81: /* TODO: HOP */ - case 0x82: /* TODO: BPH */ - case 0x83: /* TODO: NBH */ - case 0x84: /* TODO: IND */ - break; - case 0x85: /* NEL -- Next line */ - tnewline(1); /* always go to first col */ - break; - case 0x86: /* TODO: SSA */ - case 0x87: /* TODO: ESA */ - break; - case 0x88: /* HTS -- Horizontal tab stop */ - term.tabs[term.c.x] = 1; - break; - case 0x89: /* TODO: HTJ */ - case 0x8a: /* TODO: VTS */ - case 0x8b: /* TODO: PLD */ - case 0x8c: /* TODO: PLU */ - case 0x8d: /* TODO: RI */ - case 0x8e: /* TODO: SS2 */ - case 0x8f: /* TODO: SS3 */ - case 0x91: /* TODO: PU1 */ - case 0x92: /* TODO: PU2 */ - case 0x93: /* TODO: STS */ - case 0x94: /* TODO: CCH */ - case 0x95: /* TODO: MW */ - case 0x96: /* TODO: SPA */ - case 0x97: /* TODO: EPA */ - case 0x98: /* TODO: SOS */ - case 0x99: /* TODO: SGCI */ - break; - case 0x9a: /* DECID -- Identify Terminal */ - ttywrite(vtiden, strlen(vtiden), 0); - break; - case 0x9b: /* TODO: CSI */ - case 0x9c: /* TODO: ST */ - break; - case 0x90: /* DCS -- Device Control String */ - case 0x9d: /* OSC -- Operating System Command */ - case 0x9e: /* PM -- Privacy Message */ - case 0x9f: /* APC -- Application Program Command */ - tstrsequence(ascii); - return; - } - /* only CAN, SUB, \a and C1 chars interrupt a sequence */ - term.esc &= ~(ESC_STR_END|ESC_STR); -} - -/* - * returns 1 when the sequence is finished and it hasn't to read - * more characters for this sequence, otherwise 0 - */ -int -eschandle(uchar ascii) -{ - switch (ascii) { - case '[': - term.esc |= ESC_CSI; - return 0; - case '#': - term.esc |= ESC_TEST; - return 0; - case '%': - term.esc |= ESC_UTF8; - return 0; - case 'P': /* DCS -- Device Control String */ - case '_': /* APC -- Application Program Command */ - case '^': /* PM -- Privacy Message */ - case ']': /* OSC -- Operating System Command */ - case 'k': /* old title set compatibility */ - tstrsequence(ascii); - return 0; - case 'n': /* LS2 -- Locking shift 2 */ - case 'o': /* LS3 -- Locking shift 3 */ - term.charset = 2 + (ascii - 'n'); - break; - case '(': /* GZD4 -- set primary charset G0 */ - case ')': /* G1D4 -- set secondary charset G1 */ - case '*': /* G2D4 -- set tertiary charset G2 */ - case '+': /* G3D4 -- set quaternary charset G3 */ - term.icharset = ascii - '('; - term.esc |= ESC_ALTCHARSET; - return 0; - case 'D': /* IND -- Linefeed */ - if (term.c.y == term.bot) { - tscrollup(term.top, 1); - } else { - tmoveto(term.c.x, term.c.y+1); - } - break; - case 'E': /* NEL -- Next line */ - tnewline(1); /* always go to first col */ - break; - case 'H': /* HTS -- Horizontal tab stop */ - term.tabs[term.c.x] = 1; - break; - case 'M': /* RI -- Reverse index */ - if (term.c.y == term.top) { - tscrolldown(term.top, 1); - } else { - tmoveto(term.c.x, term.c.y-1); - } - break; - case 'Z': /* DECID -- Identify Terminal */ - ttywrite(vtiden, strlen(vtiden), 0); - break; - case 'c': /* RIS -- Reset to initial state */ - treset(); - resettitle(); - xloadcols(); - break; - case '=': /* DECPAM -- Application keypad */ - xsetmode(1, MODE_APPKEYPAD); - break; - case '>': /* DECPNM -- Normal keypad */ - xsetmode(0, MODE_APPKEYPAD); - break; - case '7': /* DECSC -- Save Cursor */ - tcursor(CURSOR_SAVE); - break; - case '8': /* DECRC -- Restore Cursor */ - tcursor(CURSOR_LOAD); - break; - case '\\': /* ST -- String Terminator */ - if (term.esc & ESC_STR_END) - strhandle(); - break; - default: - fprintf(stderr, "erresc: unknown sequence ESC 0x%02X '%c'\n", - (uchar) ascii, isprint(ascii)? ascii:'.'); - break; - } - return 1; -} - -void -tputc(Rune u) -{ - char c[UTF_SIZ]; - int control; - int width, len; - Glyph *gp; - - control = ISCONTROL(u); - if (u < 127 || !IS_SET(MODE_UTF8)) { - c[0] = u; - width = len = 1; - } else { - len = utf8encode(u, c); - if (!control && (width = wcwidth(u)) == -1) - width = 1; - } - - if (IS_SET(MODE_PRINT)) - tprinter(c, len); - - /* - * STR sequence must be checked before anything else - * because it uses all following characters until it - * receives a ESC, a SUB, a ST or any other C1 control - * character. - */ - if (term.esc & ESC_STR) { - if (u == '\a' || u == 030 || u == 032 || u == 033 || - ISCONTROLC1(u)) { - term.esc &= ~(ESC_START|ESC_STR); - term.esc |= ESC_STR_END; - goto check_control_code; - } - - if (strescseq.len+len >= strescseq.siz) { - /* - * Here is a bug in terminals. If the user never sends - * some code to stop the str or esc command, then st - * will stop responding. But this is better than - * silently failing with unknown characters. At least - * then users will report back. - * - * In the case users ever get fixed, here is the code: - */ - /* - * term.esc = 0; - * strhandle(); - */ - if (strescseq.siz > (SIZE_MAX - UTF_SIZ) / 2) - return; - strescseq.siz *= 2; - strescseq.buf = xrealloc(strescseq.buf, strescseq.siz); - } - - memmove(&strescseq.buf[strescseq.len], c, len); - strescseq.len += len; - return; - } - -check_control_code: - /* - * Actions of control codes must be performed as soon they arrive - * because they can be embedded inside a control sequence, and - * they must not cause conflicts with sequences. - */ - if (control) { - tcontrolcode(u); - /* - * control codes are not shown ever - */ - if (!term.esc) - term.lastc = 0; - return; - } else if (term.esc & ESC_START) { - if (term.esc & ESC_CSI) { - csiescseq.buf[csiescseq.len++] = u; - if (BETWEEN(u, 0x40, 0x7E) - || csiescseq.len >= \ - sizeof(csiescseq.buf)-1) { - term.esc = 0; - csiparse(); - csihandle(); - } - return; - } else if (term.esc & ESC_UTF8) { - tdefutf8(u); - } else if (term.esc & ESC_ALTCHARSET) { - tdeftran(u); - } else if (term.esc & ESC_TEST) { - tdectest(u); - } else { - if (!eschandle(u)) - return; - /* sequence already finished */ - } - term.esc = 0; - /* - * All characters which form part of a sequence are not - * printed - */ - return; - } - if (selected(term.c.x, term.c.y)) - selclear(); - - gp = &term.line[term.c.y][term.c.x]; - if (IS_SET(MODE_WRAP) && (term.c.state & CURSOR_WRAPNEXT)) { - gp->mode |= ATTR_WRAP; - tnewline(1); - gp = &term.line[term.c.y][term.c.x]; - } - - if (IS_SET(MODE_INSERT) && term.c.x+width < term.col) - memmove(gp+width, gp, (term.col - term.c.x - width) * sizeof(Glyph)); - - if (term.c.x+width > term.col) { - tnewline(1); - gp = &term.line[term.c.y][term.c.x]; - } - - tsetchar(u, &term.c.attr, term.c.x, term.c.y); - term.lastc = u; - - if (width == 2) { - gp->mode |= ATTR_WIDE; - if (term.c.x+1 < term.col) { - gp[1].u = '\0'; - gp[1].mode = ATTR_WDUMMY; - } - } - if (term.c.x+width < term.col) { - tmoveto(term.c.x+width, term.c.y); - } else { - term.c.state |= CURSOR_WRAPNEXT; - } -} - -int -twrite(const char *buf, int buflen, int show_ctrl) -{ - int charsize; - Rune u; - int n; - - for (n = 0; n < buflen; n += charsize) { - if (IS_SET(MODE_UTF8)) { - /* process a complete utf8 char */ - charsize = utf8decode(buf + n, &u, buflen - n); - if (charsize == 0) - break; - } else { - u = buf[n] & 0xFF; - charsize = 1; - } - if (show_ctrl && ISCONTROL(u)) { - if (u & 0x80) { - u &= 0x7f; - tputc('^'); - tputc('['); - } else if (u != '\n' && u != '\r' && u != '\t') { - u ^= 0x40; - tputc('^'); - } - } - tputc(u); - } - return n; -} - -void -tresize(int col, int row) -{ - int i; - int minrow = MIN(row, term.row); - int mincol = MIN(col, term.col); - int *bp; - TCursor c; - - if (col < 1 || row < 1) { - fprintf(stderr, - "tresize: error resizing to %dx%d\n", col, row); - return; - } - - /* - * slide screen to keep cursor where we expect it - - * tscrollup would work here, but we can optimize to - * memmove because we're freeing the earlier lines - */ - for (i = 0; i <= term.c.y - row; i++) { - free(term.line[i]); - free(term.alt[i]); - } - /* ensure that both src and dst are not NULL */ - if (i > 0) { - memmove(term.line, term.line + i, row * sizeof(Line)); - memmove(term.alt, term.alt + i, row * sizeof(Line)); - } - for (i += row; i < term.row; i++) { - free(term.line[i]); - free(term.alt[i]); - } - - /* resize to new height */ - term.line = xrealloc(term.line, row * sizeof(Line)); - term.alt = xrealloc(term.alt, row * sizeof(Line)); - term.dirty = xrealloc(term.dirty, row * sizeof(*term.dirty)); - term.tabs = xrealloc(term.tabs, col * sizeof(*term.tabs)); - - /* resize each row to new width, zero-pad if needed */ - for (i = 0; i < minrow; i++) { - term.line[i] = xrealloc(term.line[i], col * sizeof(Glyph)); - term.alt[i] = xrealloc(term.alt[i], col * sizeof(Glyph)); - } - - /* allocate any new rows */ - for (/* i = minrow */; i < row; i++) { - term.line[i] = xmalloc(col * sizeof(Glyph)); - term.alt[i] = xmalloc(col * sizeof(Glyph)); - } - if (col > term.col) { - bp = term.tabs + term.col; - - memset(bp, 0, sizeof(*term.tabs) * (col - term.col)); - while (--bp > term.tabs && !*bp) - /* nothing */ ; - for (bp += tabspaces; bp < term.tabs + col; bp += tabspaces) - *bp = 1; - } - /* update terminal size */ - term.col = col; - term.row = row; - /* reset scrolling region */ - tsetscroll(0, row-1); - /* make use of the LIMIT in tmoveto */ - tmoveto(term.c.x, term.c.y); - /* Clearing both screens (it makes dirty all lines) */ - c = term.c; - for (i = 0; i < 2; i++) { - if (mincol < col && 0 < minrow) { - tclearregion(mincol, 0, col - 1, minrow - 1); - } - if (0 < col && minrow < row) { - tclearregion(0, minrow, col - 1, row - 1); - } - tswapscreen(); - tcursor(CURSOR_LOAD); - } - term.c = c; -} - -void -resettitle(void) -{ - xsettitle(NULL); -} - -void -drawregion(int x1, int y1, int x2, int y2) -{ - int y; - - for (y = y1; y < y2; y++) { - if (!term.dirty[y]) - continue; - - term.dirty[y] = 0; - xdrawline(term.line[y], x1, y, x2); - } -} - -void -draw(void) -{ - int cx = term.c.x, ocx = term.ocx, ocy = term.ocy; - - if (!xstartdraw()) - return; - - /* adjust cursor position */ - LIMIT(term.ocx, 0, term.col-1); - LIMIT(term.ocy, 0, term.row-1); - if (term.line[term.ocy][term.ocx].mode & ATTR_WDUMMY) - term.ocx--; - if (term.line[term.c.y][cx].mode & ATTR_WDUMMY) - cx--; - - drawregion(0, 0, term.col, term.row); - xdrawcursor(cx, term.c.y, term.line[term.c.y][cx], - term.ocx, term.ocy, term.line[term.ocy][term.ocx]); - term.ocx = cx; - term.ocy = term.c.y; - xfinishdraw(); - if (ocx != term.ocx || ocy != term.ocy) - xximspot(term.ocx, term.ocy); -} - -void -redraw(void) -{ - tfulldirt(); - draw(); -} diff --git a/st/st.h b/st/st.h deleted file mode 100644 index 3d351b6..0000000 --- a/st/st.h +++ /dev/null @@ -1,125 +0,0 @@ -/* See LICENSE for license details. */ - -#include -#include - -/* macros */ -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define MAX(a, b) ((a) < (b) ? (b) : (a)) -#define LEN(a) (sizeof(a) / sizeof(a)[0]) -#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b)) -#define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d)) -#define DEFAULT(a, b) (a) = (a) ? (a) : (b) -#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x) -#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || \ - (a).bg != (b).bg) -#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \ - (t1.tv_nsec-t2.tv_nsec)/1E6) -#define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit))) - -#define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b)) -#define IS_TRUECOL(x) (1 << 24 & (x)) - -enum glyph_attribute { - ATTR_NULL = 0, - ATTR_BOLD = 1 << 0, - ATTR_FAINT = 1 << 1, - ATTR_ITALIC = 1 << 2, - ATTR_UNDERLINE = 1 << 3, - ATTR_BLINK = 1 << 4, - ATTR_REVERSE = 1 << 5, - ATTR_INVISIBLE = 1 << 6, - ATTR_STRUCK = 1 << 7, - ATTR_WRAP = 1 << 8, - ATTR_WIDE = 1 << 9, - ATTR_WDUMMY = 1 << 10, - ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT, -}; - -enum selection_mode { - SEL_IDLE = 0, - SEL_EMPTY = 1, - SEL_READY = 2 -}; - -enum selection_type { - SEL_REGULAR = 1, - SEL_RECTANGULAR = 2 -}; - -enum selection_snap { - SNAP_WORD = 1, - SNAP_LINE = 2 -}; - -typedef unsigned char uchar; -typedef unsigned int uint; -typedef unsigned long ulong; -typedef unsigned short ushort; - -typedef uint_least32_t Rune; - -#define Glyph Glyph_ -typedef struct { - Rune u; /* character code */ - ushort mode; /* attribute flags */ - uint32_t fg; /* foreground */ - uint32_t bg; /* background */ -} Glyph; - -typedef Glyph *Line; - -typedef union { - int i; - uint ui; - float f; - const void *v; - const char *s; -} Arg; - -void die(const char *, ...); -void redraw(void); -void draw(void); - -void printscreen(const Arg *); -void printsel(const Arg *); -void sendbreak(const Arg *); -void toggleprinter(const Arg *); - -int tattrset(int); -void tnew(int, int); -void tresize(int, int); -void tsetdirtattr(int); -void ttyhangup(void); -int ttynew(char *, char *, char *, char **); -size_t ttyread(void); -void ttyresize(int, int); -void ttywrite(const char *, size_t, int); - -void resettitle(void); - -void selclear(void); -void selinit(void); -void selstart(int, int, int); -void selextend(int, int, int, int); -int selected(int, int); -char *getsel(void); - -size_t utf8encode(Rune, char *); - -void *xmalloc(size_t); -void *xrealloc(void *, size_t); -char *xstrdup(char *); - -/* config.h globals */ -extern char *utmp; -extern char *scroll; -extern char *stty_args; -extern char *vtiden; -extern wchar_t *worddelimiters; -extern int allowaltscreen; -extern int allowwindowops; -extern char *termname; -extern unsigned int tabspaces; -extern unsigned int defaultfg; -extern unsigned int defaultbg; diff --git a/st/st.info b/st/st.info deleted file mode 100644 index 8201ad6..0000000 --- a/st/st.info +++ /dev/null @@ -1,239 +0,0 @@ -st-mono| simpleterm monocolor, - acsc=+C\,D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~, - am, - bce, - bel=^G, - blink=\E[5m, - bold=\E[1m, - cbt=\E[Z, - cvvis=\E[?25h, - civis=\E[?25l, - clear=\E[H\E[2J, - cnorm=\E[?12l\E[?25h, - colors#2, - cols#80, - cr=^M, - csr=\E[%i%p1%d;%p2%dr, - cub=\E[%p1%dD, - cub1=^H, - cud1=^J, - cud=\E[%p1%dB, - cuf1=\E[C, - cuf=\E[%p1%dC, - cup=\E[%i%p1%d;%p2%dH, - cuu1=\E[A, - cuu=\E[%p1%dA, - dch=\E[%p1%dP, - dch1=\E[P, - dim=\E[2m, - dl=\E[%p1%dM, - dl1=\E[M, - ech=\E[%p1%dX, - ed=\E[J, - el=\E[K, - el1=\E[1K, - enacs=\E)0, - flash=\E[?5h$<80/>\E[?5l, - fsl=^G, - home=\E[H, - hpa=\E[%i%p1%dG, - hs, - ht=^I, - hts=\EH, - ich=\E[%p1%d@, - il1=\E[L, - il=\E[%p1%dL, - ind=^J, - indn=\E[%p1%dS, - invis=\E[8m, - is2=\E[4l\E>\E[?1034l, - it#8, - kel=\E[1;2F, - ked=\E[1;5F, - ka1=\E[1~, - ka3=\E[5~, - kc1=\E[4~, - kc3=\E[6~, - kbs=\177, - kcbt=\E[Z, - kb2=\EOu, - kcub1=\EOD, - kcud1=\EOB, - kcuf1=\EOC, - kcuu1=\EOA, - kDC=\E[3;2~, - kent=\EOM, - kEND=\E[1;2F, - kIC=\E[2;2~, - kNXT=\E[6;2~, - kPRV=\E[5;2~, - kHOM=\E[1;2H, - kLFT=\E[1;2D, - kRIT=\E[1;2C, - kind=\E[1;2B, - kri=\E[1;2A, - kclr=\E[3;5~, - kdl1=\E[3;2~, - kdch1=\E[3~, - kich1=\E[2~, - kend=\E[4~, - kf1=\EOP, - kf2=\EOQ, - kf3=\EOR, - kf4=\EOS, - kf5=\E[15~, - kf6=\E[17~, - kf7=\E[18~, - kf8=\E[19~, - kf9=\E[20~, - kf10=\E[21~, - kf11=\E[23~, - kf12=\E[24~, - kf13=\E[1;2P, - kf14=\E[1;2Q, - kf15=\E[1;2R, - kf16=\E[1;2S, - kf17=\E[15;2~, - kf18=\E[17;2~, - kf19=\E[18;2~, - kf20=\E[19;2~, - kf21=\E[20;2~, - kf22=\E[21;2~, - kf23=\E[23;2~, - kf24=\E[24;2~, - kf25=\E[1;5P, - kf26=\E[1;5Q, - kf27=\E[1;5R, - kf28=\E[1;5S, - kf29=\E[15;5~, - kf30=\E[17;5~, - kf31=\E[18;5~, - kf32=\E[19;5~, - kf33=\E[20;5~, - kf34=\E[21;5~, - kf35=\E[23;5~, - kf36=\E[24;5~, - kf37=\E[1;6P, - kf38=\E[1;6Q, - kf39=\E[1;6R, - kf40=\E[1;6S, - kf41=\E[15;6~, - kf42=\E[17;6~, - kf43=\E[18;6~, - kf44=\E[19;6~, - kf45=\E[20;6~, - kf46=\E[21;6~, - kf47=\E[23;6~, - kf48=\E[24;6~, - kf49=\E[1;3P, - kf50=\E[1;3Q, - kf51=\E[1;3R, - kf52=\E[1;3S, - kf53=\E[15;3~, - kf54=\E[17;3~, - kf55=\E[18;3~, - kf56=\E[19;3~, - kf57=\E[20;3~, - kf58=\E[21;3~, - kf59=\E[23;3~, - kf60=\E[24;3~, - kf61=\E[1;4P, - kf62=\E[1;4Q, - kf63=\E[1;4R, - khome=\E[1~, - kil1=\E[2;5~, - krmir=\E[2;2~, - knp=\E[6~, - kmous=\E[M, - kpp=\E[5~, - lines#24, - mir, - msgr, - npc, - op=\E[39;49m, - pairs#64, - mc0=\E[i, - mc4=\E[4i, - mc5=\E[5i, - rc=\E8, - rev=\E[7m, - ri=\EM, - rin=\E[%p1%dT, - ritm=\E[23m, - rmacs=\E(B, - rmcup=\E[?1049l, - rmir=\E[4l, - rmkx=\E[?1l\E>, - rmso=\E[27m, - rmul=\E[24m, - rs1=\Ec, - rs2=\E[4l\E>\E[?1034l, - sc=\E7, - sitm=\E[3m, - sgr0=\E[0m, - smacs=\E(0, - smcup=\E[?1049h, - smir=\E[4h, - smkx=\E[?1h\E=, - smso=\E[7m, - smul=\E[4m, - tbc=\E[3g, - tsl=\E]0;, - xenl, - vpa=\E[%i%p1%dd, -# XTerm extensions - rmxx=\E[29m, - smxx=\E[9m, -# disabled rep for now: causes some issues with older ncurses versions. -# rep=%p1%c\E[%p2%{1}%-%db, -# tmux extensions, see TERMINFO EXTENSIONS in tmux(1) - Tc, - Ms=\E]52;%p1%s;%p2%s\007, - Se=\E[2 q, - Ss=\E[%p1%d q, - -st| simpleterm, - use=st-mono, - colors#8, - setab=\E[4%p1%dm, - setaf=\E[3%p1%dm, - setb=\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, - setf=\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m, - sgr=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m, - -st-256color| simpleterm with 256 colors, - use=st, - ccc, - colors#256, - oc=\E]104\007, - pairs#32767, -# Nicked from xterm-256color - initc=\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\, - setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m, - setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m, - -st-meta| simpleterm with meta key, - use=st, - km, - rmm=\E[?1034l, - smm=\E[?1034h, - rs2=\E[4l\E>\E[?1034h, - is2=\E[4l\E>\E[?1034h, - -st-meta-256color| simpleterm with meta key and 256 colors, - use=st-256color, - km, - rmm=\E[?1034l, - smm=\E[?1034h, - rs2=\E[4l\E>\E[?1034h, - is2=\E[4l\E>\E[?1034h, - -st-bs| simpleterm with backspace as backspace, - use=st, - kbs=\010, - kdch1=\177, - -st-bs-256color| simpleterm with backspace as backspace and 256colors, - use=st-256color, - kbs=\010, - kdch1=\177, diff --git a/st/win.h b/st/win.h deleted file mode 100644 index e6e4369..0000000 --- a/st/win.h +++ /dev/null @@ -1,40 +0,0 @@ -/* See LICENSE for license details. */ - -enum win_mode { - MODE_VISIBLE = 1 << 0, - MODE_FOCUSED = 1 << 1, - MODE_APPKEYPAD = 1 << 2, - MODE_MOUSEBTN = 1 << 3, - MODE_MOUSEMOTION = 1 << 4, - MODE_REVERSE = 1 << 5, - MODE_KBDLOCK = 1 << 6, - MODE_HIDE = 1 << 7, - MODE_APPCURSOR = 1 << 8, - MODE_MOUSESGR = 1 << 9, - MODE_8BIT = 1 << 10, - MODE_BLINK = 1 << 11, - MODE_FBLINK = 1 << 12, - MODE_FOCUS = 1 << 13, - MODE_MOUSEX10 = 1 << 14, - MODE_MOUSEMANY = 1 << 15, - MODE_BRCKTPASTE = 1 << 16, - MODE_NUMLOCK = 1 << 17, - MODE_MOUSE = MODE_MOUSEBTN|MODE_MOUSEMOTION|MODE_MOUSEX10\ - |MODE_MOUSEMANY, -}; - -void xbell(void); -void xclipcopy(void); -void xdrawcursor(int, int, Glyph, int, int, Glyph); -void xdrawline(Line, int, int, int); -void xfinishdraw(void); -void xloadcols(void); -int xsetcolorname(int, const char *); -void xseticontitle(char *); -void xsettitle(char *); -int xsetcursor(int); -void xsetmode(int, unsigned int); -void xsetpointermotion(int); -void xsetsel(char *); -int xstartdraw(void); -void xximspot(int, int); diff --git a/st/x.c b/st/x.c deleted file mode 100644 index eee7b0b..0000000 --- a/st/x.c +++ /dev/null @@ -1,2136 +0,0 @@ -/* See LICENSE for license details. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -char *argv0; -#include "arg.h" -#include "st.h" -#include "win.h" - -/* types used in config.h */ -typedef struct { - uint mod; - KeySym keysym; - void (*func)(const Arg *); - const Arg arg; -} Shortcut; - -typedef struct { - uint mod; - uint button; - void (*func)(const Arg *); - const Arg arg; - uint release; -} MouseShortcut; - -typedef struct { - KeySym k; - uint mask; - char *s; - /* three-valued logic variables: 0 indifferent, 1 on, -1 off */ - signed char appkey; /* application keypad */ - signed char appcursor; /* application cursor */ -} Key; - -/* X modifiers */ -#define XK_ANY_MOD UINT_MAX -#define XK_NO_MOD 0 -#define XK_SWITCH_MOD (1<<13) - -/* function definitions used in config.h */ -static void clipcopy(const Arg *); -static void clippaste(const Arg *); -static void numlock(const Arg *); -static void selpaste(const Arg *); -static void zoom(const Arg *); -static void zoomabs(const Arg *); -static void zoomreset(const Arg *); -static void ttysend(const Arg *); - -/* config.h for applying patches and the configuration. */ -#include "config.h" - -/* XEMBED messages */ -#define XEMBED_FOCUS_IN 4 -#define XEMBED_FOCUS_OUT 5 - -/* macros */ -#define IS_SET(flag) ((win.mode & (flag)) != 0) -#define TRUERED(x) (((x) & 0xff0000) >> 8) -#define TRUEGREEN(x) (((x) & 0xff00)) -#define TRUEBLUE(x) (((x) & 0xff) << 8) - -typedef XftDraw *Draw; -typedef XftColor Color; -typedef XftGlyphFontSpec GlyphFontSpec; - -/* Purely graphic info */ -typedef struct { - int tw, th; /* tty width and height */ - int w, h; /* window width and height */ - int ch; /* char height */ - int cw; /* char width */ - int mode; /* window state/mode flags */ - int cursor; /* cursor style */ -} TermWindow; - -typedef struct { - Display *dpy; - Colormap cmap; - Window win; - Drawable buf; - GlyphFontSpec *specbuf; /* font spec buffer used for rendering */ - Atom xembed, wmdeletewin, netwmname, netwmiconname, netwmpid; - struct { - XIM xim; - XIC xic; - XPoint spot; - XVaNestedList spotlist; - } ime; - Draw draw; - Visual *vis; - XSetWindowAttributes attrs; - int scr; - int isfixed; /* is fixed geometry? */ - int l, t; /* left and top offset */ - int gm; /* geometry mask */ -} XWindow; - -typedef struct { - Atom xtarget; - char *primary, *clipboard; - struct timespec tclick1; - struct timespec tclick2; -} XSelection; - -/* Font structure */ -#define Font Font_ -typedef struct { - int height; - int width; - int ascent; - int descent; - int badslant; - int badweight; - short lbearing; - short rbearing; - XftFont *match; - FcFontSet *set; - FcPattern *pattern; -} Font; - -/* Drawing Context */ -typedef struct { - Color *col; - size_t collen; - Font font, bfont, ifont, ibfont; - GC gc; -} DC; - -static inline ushort sixd_to_16bit(int); -static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int); -static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int); -static void xdrawglyph(Glyph, int, int); -static void xclear(int, int, int, int); -static int xgeommasktogravity(int); -static int ximopen(Display *); -static void ximinstantiate(Display *, XPointer, XPointer); -static void ximdestroy(XIM, XPointer, XPointer); -static int xicdestroy(XIC, XPointer, XPointer); -static void xinit(int, int); -static void cresize(int, int); -static void xresize(int, int); -static void xhints(void); -static int xloadcolor(int, const char *, Color *); -static int xloadfont(Font *, FcPattern *); -static void xloadfonts(char *, double); -static void xloadsparefont(); -static void xunloadfont(Font *); -static void xunloadfonts(void); -static void xsetenv(void); -static void xseturgency(int); -static int evcol(XEvent *); -static int evrow(XEvent *); - -static void expose(XEvent *); -static void visibility(XEvent *); -static void unmap(XEvent *); -static void kpress(XEvent *); -static void cmessage(XEvent *); -static void resize(XEvent *); -static void focus(XEvent *); -static uint buttonmask(uint); -static int mouseaction(XEvent *, uint); -static void brelease(XEvent *); -static void bpress(XEvent *); -static void bmotion(XEvent *); -static void propnotify(XEvent *); -static void selnotify(XEvent *); -static void selclear_(XEvent *); -static void selrequest(XEvent *); -static void setsel(char *, Time); -static void mousesel(XEvent *, int); -static void mousereport(XEvent *); -static char *kmap(KeySym, uint); -static int match(uint, uint); - -static void run(void); -static void usage(void); - -static void (*handler[LASTEvent])(XEvent *) = { - [KeyPress] = kpress, - [ClientMessage] = cmessage, - [ConfigureNotify] = resize, - [VisibilityNotify] = visibility, - [UnmapNotify] = unmap, - [Expose] = expose, - [FocusIn] = focus, - [FocusOut] = focus, - [MotionNotify] = bmotion, - [ButtonPress] = bpress, - [ButtonRelease] = brelease, -/* - * Uncomment if you want the selection to disappear when you select something - * different in another window. - */ -/* [SelectionClear] = selclear_, */ - [SelectionNotify] = selnotify, -/* - * PropertyNotify is only turned on when there is some INCR transfer happening - * for the selection retrieval. - */ - [PropertyNotify] = propnotify, - [SelectionRequest] = selrequest, -}; - -/* Globals */ -static DC dc; -static XWindow xw; -static XSelection xsel; -static TermWindow win; - -/* Font Ring Cache */ -enum { - FRC_NORMAL, - FRC_ITALIC, - FRC_BOLD, - FRC_ITALICBOLD -}; - -typedef struct { - XftFont *font; - int flags; - Rune unicodep; -} Fontcache; - -/* Fontcache is an array now. A new font will be appended to the array. */ -static Fontcache *frc = NULL; -static int frclen = 0; -static int frccap = 0; -static char *usedfont = NULL; -static double usedfontsize = 0; -static double defaultfontsize = 0; - -static char *opt_class = NULL; -static char **opt_cmd = NULL; -static char *opt_embed = NULL; -static char *opt_font = NULL; -static char *opt_io = NULL; -static char *opt_line = NULL; -static char *opt_name = NULL; -static char *opt_title = NULL; - -static int oldbutton = 3; /* button event on startup: 3 = release */ - -void -clipcopy(const Arg *dummy) -{ - Atom clipboard; - - free(xsel.clipboard); - xsel.clipboard = NULL; - - if (xsel.primary != NULL) { - xsel.clipboard = xstrdup(xsel.primary); - clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); - XSetSelectionOwner(xw.dpy, clipboard, xw.win, CurrentTime); - } -} - -void -clippaste(const Arg *dummy) -{ - Atom clipboard; - - clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); - XConvertSelection(xw.dpy, clipboard, xsel.xtarget, clipboard, - xw.win, CurrentTime); -} - -void -selpaste(const Arg *dummy) -{ - XConvertSelection(xw.dpy, XA_PRIMARY, xsel.xtarget, XA_PRIMARY, - xw.win, CurrentTime); -} - -void -numlock(const Arg *dummy) -{ - win.mode ^= MODE_NUMLOCK; -} - -void -zoom(const Arg *arg) -{ - Arg larg; - - larg.f = usedfontsize + arg->f; - zoomabs(&larg); -} - -void -zoomabs(const Arg *arg) -{ - xunloadfonts(); - xloadfonts(usedfont, arg->f); - xloadsparefont(); - cresize(0, 0); - - xunloadfonts(); - xloadfonts(usedfont, arg->f); - xloadsparefont(); - cresize(0, 0); - - - redraw(); - xhints(); -} - -void -zoomreset(const Arg *arg) -{ - Arg larg; - - if (defaultfontsize > 0) { - larg.f = defaultfontsize; - zoomabs(&larg); - } -} - -void -ttysend(const Arg *arg) -{ - ttywrite(arg->s, strlen(arg->s), 1); -} - -int -evcol(XEvent *e) -{ - int x = e->xbutton.x - borderpx; - LIMIT(x, 0, win.tw - 1); - return x / win.cw; -} - -int -evrow(XEvent *e) -{ - int y = e->xbutton.y - borderpx; - LIMIT(y, 0, win.th - 1); - return y / win.ch; -} - -void -mousesel(XEvent *e, int done) -{ - int type, seltype = SEL_REGULAR; - uint state = e->xbutton.state & ~(Button1Mask | forcemousemod); - - for (type = 1; type < LEN(selmasks); ++type) { - if (match(selmasks[type], state)) { - seltype = type; - break; - } - } - selextend(evcol(e), evrow(e), seltype, done); - if (done) - setsel(getsel(), e->xbutton.time); -} - -void -mousereport(XEvent *e) -{ - int len, x = evcol(e), y = evrow(e), - button = e->xbutton.button, state = e->xbutton.state; - char buf[40]; - static int ox, oy; - - /* from urxvt */ - if (e->xbutton.type == MotionNotify) { - if (x == ox && y == oy) - return; - if (!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY)) - return; - /* MOUSE_MOTION: no reporting if no button is pressed */ - if (IS_SET(MODE_MOUSEMOTION) && oldbutton == 3) - return; - - button = oldbutton + 32; - ox = x; - oy = y; - } else { - if (!IS_SET(MODE_MOUSESGR) && e->xbutton.type == ButtonRelease) { - button = 3; - } else { - button -= Button1; - if (button >= 3) - button += 64 - 3; - } - if (e->xbutton.type == ButtonPress) { - oldbutton = button; - ox = x; - oy = y; - } else if (e->xbutton.type == ButtonRelease) { - oldbutton = 3; - /* MODE_MOUSEX10: no button release reporting */ - if (IS_SET(MODE_MOUSEX10)) - return; - if (button == 64 || button == 65) - return; - } - } - - if (!IS_SET(MODE_MOUSEX10)) { - button += ((state & ShiftMask ) ? 4 : 0) - + ((state & Mod4Mask ) ? 8 : 0) - + ((state & ControlMask) ? 16 : 0); - } - - if (IS_SET(MODE_MOUSESGR)) { - len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c", - button, x+1, y+1, - e->xbutton.type == ButtonRelease ? 'm' : 'M'); - } else if (x < 223 && y < 223) { - len = snprintf(buf, sizeof(buf), "\033[M%c%c%c", - 32+button, 32+x+1, 32+y+1); - } else { - return; - } - - ttywrite(buf, len, 0); -} - -uint -buttonmask(uint button) -{ - return button == Button1 ? Button1Mask - : button == Button2 ? Button2Mask - : button == Button3 ? Button3Mask - : button == Button4 ? Button4Mask - : button == Button5 ? Button5Mask - : 0; -} - -int -mouseaction(XEvent *e, uint release) -{ - MouseShortcut *ms; - - /* ignore Buttonmask for Button - it's set on release */ - uint state = e->xbutton.state & ~buttonmask(e->xbutton.button); - - for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) { - if (ms->release == release && - ms->button == e->xbutton.button && - (match(ms->mod, state) || /* exact or forced */ - match(ms->mod, state & ~forcemousemod))) { - ms->func(&(ms->arg)); - return 1; - } - } - - return 0; -} - -void -bpress(XEvent *e) -{ - struct timespec now; - int snap; - - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { - mousereport(e); - return; - } - - if (mouseaction(e, 0)) - return; - - if (e->xbutton.button == Button1) { - /* - * If the user clicks below predefined timeouts specific - * snapping behaviour is exposed. - */ - clock_gettime(CLOCK_MONOTONIC, &now); - if (TIMEDIFF(now, xsel.tclick2) <= tripleclicktimeout) { - snap = SNAP_LINE; - } else if (TIMEDIFF(now, xsel.tclick1) <= doubleclicktimeout) { - snap = SNAP_WORD; - } else { - snap = 0; - } - xsel.tclick2 = xsel.tclick1; - xsel.tclick1 = now; - - selstart(evcol(e), evrow(e), snap); - } -} - -void -propnotify(XEvent *e) -{ - XPropertyEvent *xpev; - Atom clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); - - xpev = &e->xproperty; - if (xpev->state == PropertyNewValue && - (xpev->atom == XA_PRIMARY || - xpev->atom == clipboard)) { - selnotify(e); - } -} - -void -selnotify(XEvent *e) -{ - ulong nitems, ofs, rem; - int format; - uchar *data, *last, *repl; - Atom type, incratom, property = None; - - incratom = XInternAtom(xw.dpy, "INCR", 0); - - ofs = 0; - if (e->type == SelectionNotify) - property = e->xselection.property; - else if (e->type == PropertyNotify) - property = e->xproperty.atom; - - if (property == None) - return; - - do { - if (XGetWindowProperty(xw.dpy, xw.win, property, ofs, - BUFSIZ/4, False, AnyPropertyType, - &type, &format, &nitems, &rem, - &data)) { - fprintf(stderr, "Clipboard allocation failed\n"); - return; - } - - if (e->type == PropertyNotify && nitems == 0 && rem == 0) { - /* - * If there is some PropertyNotify with no data, then - * this is the signal of the selection owner that all - * data has been transferred. We won't need to receive - * PropertyNotify events anymore. - */ - MODBIT(xw.attrs.event_mask, 0, PropertyChangeMask); - XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, - &xw.attrs); - } - - if (type == incratom) { - /* - * Activate the PropertyNotify events so we receive - * when the selection owner does send us the next - * chunk of data. - */ - MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask); - XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, - &xw.attrs); - - /* - * Deleting the property is the transfer start signal. - */ - XDeleteProperty(xw.dpy, xw.win, (int)property); - continue; - } - - /* - * As seen in getsel: - * Line endings are inconsistent in the terminal and GUI world - * copy and pasting. When receiving some selection data, - * replace all '\n' with '\r'. - * FIXME: Fix the computer world. - */ - repl = data; - last = data + nitems * format / 8; - while ((repl = memchr(repl, '\n', last - repl))) { - *repl++ = '\r'; - } - - if (IS_SET(MODE_BRCKTPASTE) && ofs == 0) - ttywrite("\033[200~", 6, 0); - ttywrite((char *)data, nitems * format / 8, 1); - if (IS_SET(MODE_BRCKTPASTE) && rem == 0) - ttywrite("\033[201~", 6, 0); - XFree(data); - /* number of 32-bit chunks returned */ - ofs += nitems * format / 32; - } while (rem > 0); - - /* - * Deleting the property again tells the selection owner to send the - * next data chunk in the property. - */ - XDeleteProperty(xw.dpy, xw.win, (int)property); -} - -void -xclipcopy(void) -{ - clipcopy(NULL); -} - -void -selclear_(XEvent *e) -{ - selclear(); -} - -void -selrequest(XEvent *e) -{ - XSelectionRequestEvent *xsre; - XSelectionEvent xev; - Atom xa_targets, string, clipboard; - char *seltext; - - xsre = (XSelectionRequestEvent *) e; - xev.type = SelectionNotify; - xev.requestor = xsre->requestor; - xev.selection = xsre->selection; - xev.target = xsre->target; - xev.time = xsre->time; - if (xsre->property == None) - xsre->property = xsre->target; - - /* reject */ - xev.property = None; - - xa_targets = XInternAtom(xw.dpy, "TARGETS", 0); - if (xsre->target == xa_targets) { - /* respond with the supported type */ - string = xsel.xtarget; - XChangeProperty(xsre->display, xsre->requestor, xsre->property, - XA_ATOM, 32, PropModeReplace, - (uchar *) &string, 1); - xev.property = xsre->property; - } else if (xsre->target == xsel.xtarget || xsre->target == XA_STRING) { - /* - * xith XA_STRING non ascii characters may be incorrect in the - * requestor. It is not our problem, use utf8. - */ - clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); - if (xsre->selection == XA_PRIMARY) { - seltext = xsel.primary; - } else if (xsre->selection == clipboard) { - seltext = xsel.clipboard; - } else { - fprintf(stderr, - "Unhandled clipboard selection 0x%lx\n", - xsre->selection); - return; - } - if (seltext != NULL) { - XChangeProperty(xsre->display, xsre->requestor, - xsre->property, xsre->target, - 8, PropModeReplace, - (uchar *)seltext, strlen(seltext)); - xev.property = xsre->property; - } - } - - /* all done, send a notification to the listener */ - if (!XSendEvent(xsre->display, xsre->requestor, 1, 0, (XEvent *) &xev)) - fprintf(stderr, "Error sending SelectionNotify event\n"); -} - -void -setsel(char *str, Time t) -{ - if (!str) - return; - - free(xsel.primary); - xsel.primary = str; - - XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t); - if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win) - selclear(); -} - -void -xsetsel(char *str) -{ - setsel(str, CurrentTime); -} - -void -brelease(XEvent *e) -{ - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { - mousereport(e); - return; - } - - if (mouseaction(e, 1)) - return; - if (e->xbutton.button == Button1) - mousesel(e, 1); -} - -void -bmotion(XEvent *e) -{ - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { - mousereport(e); - return; - } - - mousesel(e, 0); -} - -void -cresize(int width, int height) -{ - int col, row; - - if (width != 0) - win.w = width; - if (height != 0) - win.h = height; - - col = (win.w - 2 * borderpx) / win.cw; - row = (win.h - 2 * borderpx) / win.ch; - col = MAX(1, col); - row = MAX(1, row); - - tresize(col, row); - xresize(col, row); - ttyresize(win.tw, win.th); -} - -void -xresize(int col, int row) -{ - win.tw = col * win.cw; - win.th = row * win.ch; - - XFreePixmap(xw.dpy, xw.buf); - xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, - DefaultDepth(xw.dpy, xw.scr)); - XftDrawChange(xw.draw, xw.buf); - xclear(0, 0, win.w, win.h); - - /* resize to new width */ - xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec)); -} - -ushort -sixd_to_16bit(int x) -{ - return x == 0 ? 0 : 0x3737 + 0x2828 * x; -} - -int -xloadcolor(int i, const char *name, Color *ncolor) -{ - XRenderColor color = { .alpha = 0xffff }; - - if (!name) { - if (BETWEEN(i, 16, 255)) { /* 256 color */ - if (i < 6*6*6+16) { /* same colors as xterm */ - color.red = sixd_to_16bit( ((i-16)/36)%6 ); - color.green = sixd_to_16bit( ((i-16)/6) %6 ); - color.blue = sixd_to_16bit( ((i-16)/1) %6 ); - } else { /* greyscale */ - color.red = 0x0808 + 0x0a0a * (i - (6*6*6+16)); - color.green = color.blue = color.red; - } - return XftColorAllocValue(xw.dpy, xw.vis, - xw.cmap, &color, ncolor); - } else - name = colorname[i]; - } - - return XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, ncolor); -} - -void -xloadcols(void) -{ - int i; - static int loaded; - Color *cp; - - if (loaded) { - for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp) - XftColorFree(xw.dpy, xw.vis, xw.cmap, cp); - } else { - dc.collen = MAX(LEN(colorname), 256); - dc.col = xmalloc(dc.collen * sizeof(Color)); - } - - for (i = 0; i < dc.collen; i++) - if (!xloadcolor(i, NULL, &dc.col[i])) { - if (colorname[i]) - die("could not allocate color '%s'\n", colorname[i]); - else - die("could not allocate color %d\n", i); - } - loaded = 1; -} - -int -xsetcolorname(int x, const char *name) -{ - Color ncolor; - - if (!BETWEEN(x, 0, dc.collen)) - return 1; - - if (!xloadcolor(x, name, &ncolor)) - return 1; - - XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]); - dc.col[x] = ncolor; - - return 0; -} - -/* - * Absolute coordinates. - */ -void -xclear(int x1, int y1, int x2, int y2) -{ - XftDrawRect(xw.draw, - &dc.col[IS_SET(MODE_REVERSE)? defaultfg : defaultbg], - x1, y1, x2-x1, y2-y1); -} - -void -xhints(void) -{ - XClassHint class = {opt_name ? opt_name : termname, - opt_class ? opt_class : termname}; - XWMHints wm = {.flags = InputHint, .input = 1}; - XSizeHints *sizeh; - - sizeh = XAllocSizeHints(); - - sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize; - sizeh->height = win.h; - sizeh->width = win.w; - sizeh->height_inc = win.ch; - sizeh->width_inc = win.cw; - sizeh->base_height = 2 * borderpx; - sizeh->base_width = 2 * borderpx; - sizeh->min_height = win.ch + 2 * borderpx; - sizeh->min_width = win.cw + 2 * borderpx; - if (xw.isfixed) { - sizeh->flags |= PMaxSize; - sizeh->min_width = sizeh->max_width = win.w; - sizeh->min_height = sizeh->max_height = win.h; - } - if (xw.gm & (XValue|YValue)) { - sizeh->flags |= USPosition | PWinGravity; - sizeh->x = xw.l; - sizeh->y = xw.t; - sizeh->win_gravity = xgeommasktogravity(xw.gm); - } - - XSetWMProperties(xw.dpy, xw.win, NULL, NULL, NULL, 0, sizeh, &wm, - &class); - XFree(sizeh); -} - -int -xgeommasktogravity(int mask) -{ - switch (mask & (XNegative|YNegative)) { - case 0: - return NorthWestGravity; - case XNegative: - return NorthEastGravity; - case YNegative: - return SouthWestGravity; - } - - return SouthEastGravity; -} - -int -xloadfont(Font *f, FcPattern *pattern) -{ - FcPattern *configured; - FcPattern *match; - FcResult result; - XGlyphInfo extents; - int wantattr, haveattr; - - /* - * Manually configure instead of calling XftMatchFont - * so that we can use the configured pattern for - * "missing glyph" lookups. - */ - configured = FcPatternDuplicate(pattern); - if (!configured) - return 1; - - FcConfigSubstitute(NULL, configured, FcMatchPattern); - XftDefaultSubstitute(xw.dpy, xw.scr, configured); - - match = FcFontMatch(NULL, configured, &result); - if (!match) { - FcPatternDestroy(configured); - return 1; - } - - if (!(f->match = XftFontOpenPattern(xw.dpy, match))) { - FcPatternDestroy(configured); - FcPatternDestroy(match); - return 1; - } - - if ((XftPatternGetInteger(pattern, "slant", 0, &wantattr) == - XftResultMatch)) { - /* - * Check if xft was unable to find a font with the appropriate - * slant but gave us one anyway. Try to mitigate. - */ - if ((XftPatternGetInteger(f->match->pattern, "slant", 0, - &haveattr) != XftResultMatch) || haveattr < wantattr) { - f->badslant = 1; - fputs("font slant does not match\n", stderr); - } - } - - if ((XftPatternGetInteger(pattern, "weight", 0, &wantattr) == - XftResultMatch)) { - if ((XftPatternGetInteger(f->match->pattern, "weight", 0, - &haveattr) != XftResultMatch) || haveattr != wantattr) { - f->badweight = 1; - fputs("font weight does not match\n", stderr); - } - } - - XftTextExtentsUtf8(xw.dpy, f->match, - (const FcChar8 *) ascii_printable, - strlen(ascii_printable), &extents); - - f->set = NULL; - f->pattern = configured; - - f->ascent = f->match->ascent; - f->descent = f->match->descent; - f->lbearing = 0; - f->rbearing = f->match->max_advance_width; - - f->height = f->ascent + f->descent; - f->width = DIVCEIL(extents.xOff, strlen(ascii_printable)); - - return 0; -} - -void -xloadfonts(char *fontstr, double fontsize) -{ - FcPattern *pattern; - double fontval; - - if (fontstr[0] == '-') - pattern = XftXlfdParse(fontstr, False, False); - else - pattern = FcNameParse((FcChar8 *)fontstr); - - if (!pattern) - die("can't open font %s\n", fontstr); - - if (fontsize > 1) { - FcPatternDel(pattern, FC_PIXEL_SIZE); - FcPatternDel(pattern, FC_SIZE); - FcPatternAddDouble(pattern, FC_PIXEL_SIZE, (double)fontsize); - usedfontsize = fontsize; - } else { - if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) == - FcResultMatch) { - usedfontsize = fontval; - } else if (FcPatternGetDouble(pattern, FC_SIZE, 0, &fontval) == - FcResultMatch) { - usedfontsize = -1; - } else { - /* - * Default font size is 12, if none given. This is to - * have a known usedfontsize value. - */ - FcPatternAddDouble(pattern, FC_PIXEL_SIZE, 12); - usedfontsize = 12; - } - defaultfontsize = usedfontsize; - } - - if (xloadfont(&dc.font, pattern)) - die("can't open font %s\n", fontstr); - - if (usedfontsize < 0) { - FcPatternGetDouble(dc.font.match->pattern, - FC_PIXEL_SIZE, 0, &fontval); - usedfontsize = fontval; - if (fontsize == 0) - defaultfontsize = fontval; - } - - /* Setting character width and height. */ - win.cw = ceilf(dc.font.width * cwscale); - win.ch = ceilf(dc.font.height * chscale); - - FcPatternDel(pattern, FC_SLANT); - FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC); - if (xloadfont(&dc.ifont, pattern)) - die("can't open font %s\n", fontstr); - - FcPatternDel(pattern, FC_WEIGHT); - FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD); - if (xloadfont(&dc.ibfont, pattern)) - die("can't open font %s\n", fontstr); - - FcPatternDel(pattern, FC_SLANT); - FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN); - if (xloadfont(&dc.bfont, pattern)) - die("can't open font %s\n", fontstr); - - FcPatternDestroy(pattern); -} - -void -xloadsparefont() -{ - FcPattern *fontpattern, *match; - FcResult result; - - /* add font2 to font cache as first 4 entries */ - if ( font2[0] == '-' ) - fontpattern = XftXlfdParse(font2, False, False); - else - fontpattern = FcNameParse((FcChar8 *)font2); - if ( fontpattern ) { - /* Allocate memory for the new cache entries. */ - frccap += 4; - frc = xrealloc(frc, frccap * sizeof(Fontcache)); - /* add Normal */ - match = FcFontMatch(NULL, fontpattern, &result); - if ( match ) - frc[frclen].font = XftFontOpenPattern(xw.dpy, match); - if ( frc[frclen].font ) { - frc[frclen].flags = FRC_NORMAL; - frclen++; - } else - FcPatternDestroy(match); - /* add Italic */ - FcPatternDel(fontpattern, FC_SLANT); - FcPatternAddInteger(fontpattern, FC_SLANT, FC_SLANT_ITALIC); - match = FcFontMatch(NULL, fontpattern, &result); - if ( match ) - frc[frclen].font = XftFontOpenPattern(xw.dpy, match); - if ( frc[frclen].font ) { - frc[frclen].flags = FRC_ITALIC; - frclen++; - } else - FcPatternDestroy(match); - /* add Italic Bold */ - FcPatternDel(fontpattern, FC_WEIGHT); - FcPatternAddInteger(fontpattern, FC_WEIGHT, FC_WEIGHT_BOLD); - match = FcFontMatch(NULL, fontpattern, &result); - if ( match ) - frc[frclen].font = XftFontOpenPattern(xw.dpy, match); - if ( frc[frclen].font ) { - frc[frclen].flags = FRC_ITALICBOLD; - frclen++; - } else - FcPatternDestroy(match); - /* add Bold */ - FcPatternDel(fontpattern, FC_SLANT); - FcPatternAddInteger(fontpattern, FC_SLANT, FC_SLANT_ROMAN); - match = FcFontMatch(NULL, fontpattern, &result); - if ( match ) - frc[frclen].font = XftFontOpenPattern(xw.dpy, match); - if ( frc[frclen].font ) { - frc[frclen].flags = FRC_BOLD; - frclen++; - } else - FcPatternDestroy(match); - FcPatternDestroy(fontpattern); - } -} - -void -xunloadfont(Font *f) -{ - XftFontClose(xw.dpy, f->match); - FcPatternDestroy(f->pattern); - if (f->set) - FcFontSetDestroy(f->set); -} - -void -xunloadfonts(void) -{ - /* Free the loaded fonts in the font cache. */ - while (frclen > 0) - XftFontClose(xw.dpy, frc[--frclen].font); - - xunloadfont(&dc.font); - xunloadfont(&dc.bfont); - xunloadfont(&dc.ifont); - xunloadfont(&dc.ibfont); -} - -int -ximopen(Display *dpy) -{ - XIMCallback imdestroy = { .client_data = NULL, .callback = ximdestroy }; - XICCallback icdestroy = { .client_data = NULL, .callback = xicdestroy }; - - xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL); - if (xw.ime.xim == NULL) - return 0; - - if (XSetIMValues(xw.ime.xim, XNDestroyCallback, &imdestroy, NULL)) - fprintf(stderr, "XSetIMValues: " - "Could not set XNDestroyCallback.\n"); - - xw.ime.spotlist = XVaCreateNestedList(0, XNSpotLocation, &xw.ime.spot, - NULL); - - if (xw.ime.xic == NULL) { - xw.ime.xic = XCreateIC(xw.ime.xim, XNInputStyle, - XIMPreeditNothing | XIMStatusNothing, - XNClientWindow, xw.win, - XNDestroyCallback, &icdestroy, - NULL); - } - if (xw.ime.xic == NULL) - fprintf(stderr, "XCreateIC: Could not create input context.\n"); - - return 1; -} - -void -ximinstantiate(Display *dpy, XPointer client, XPointer call) -{ - if (ximopen(dpy)) - XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, - ximinstantiate, NULL); -} - -void -ximdestroy(XIM xim, XPointer client, XPointer call) -{ - xw.ime.xim = NULL; - XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, - ximinstantiate, NULL); - XFree(xw.ime.spotlist); -} - -int -xicdestroy(XIC xim, XPointer client, XPointer call) -{ - xw.ime.xic = NULL; - return 1; -} - -void -xinit(int cols, int rows) -{ - XGCValues gcvalues; - Cursor cursor; - Window parent; - pid_t thispid = getpid(); - XColor xmousefg, xmousebg; - - if (!(xw.dpy = XOpenDisplay(NULL))) - die("can't open display\n"); - xw.scr = XDefaultScreen(xw.dpy); - xw.vis = XDefaultVisual(xw.dpy, xw.scr); - - /* font */ - if (!FcInit()) - die("could not init fontconfig.\n"); - - usedfont = (opt_font == NULL)? font : opt_font; - xloadfonts(usedfont, 0); - - /* spare font (font2) */ - xloadsparefont(); - - /* colors */ - xw.cmap = XDefaultColormap(xw.dpy, xw.scr); - xloadcols(); - - /* adjust fixed window geometry */ - win.w = 2 * borderpx + cols * win.cw; - win.h = 2 * borderpx + rows * win.ch; - if (xw.gm & XNegative) - xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2; - if (xw.gm & YNegative) - xw.t += DisplayHeight(xw.dpy, xw.scr) - win.h - 2; - - /* Events */ - xw.attrs.background_pixel = dc.col[defaultbg].pixel; - xw.attrs.border_pixel = dc.col[defaultbg].pixel; - xw.attrs.bit_gravity = NorthWestGravity; - xw.attrs.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask - | ExposureMask | VisibilityChangeMask | StructureNotifyMask - | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; - xw.attrs.colormap = xw.cmap; - - if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) - parent = XRootWindow(xw.dpy, xw.scr); - xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t, - win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, - xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity - | CWEventMask | CWColormap, &xw.attrs); - - memset(&gcvalues, 0, sizeof(gcvalues)); - gcvalues.graphics_exposures = False; - dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, - &gcvalues); - xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, - DefaultDepth(xw.dpy, xw.scr)); - XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); - XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); - - /* font spec buffer */ - xw.specbuf = xmalloc(cols * sizeof(GlyphFontSpec)); - - /* Xft rendering context */ - xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap); - - /* input methods */ - if (!ximopen(xw.dpy)) { - XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, - ximinstantiate, NULL); - } - - /* white cursor, black outline */ - cursor = XCreateFontCursor(xw.dpy, mouseshape); - XDefineCursor(xw.dpy, xw.win, cursor); - - if (XParseColor(xw.dpy, xw.cmap, colorname[mousefg], &xmousefg) == 0) { - xmousefg.red = 0xffff; - xmousefg.green = 0xffff; - xmousefg.blue = 0xffff; - } - - if (XParseColor(xw.dpy, xw.cmap, colorname[mousebg], &xmousebg) == 0) { - xmousebg.red = 0x0000; - xmousebg.green = 0x0000; - xmousebg.blue = 0x0000; - } - - XRecolorCursor(xw.dpy, cursor, &xmousefg, &xmousebg); - - xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False); - xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False); - xw.netwmname = XInternAtom(xw.dpy, "_NET_WM_NAME", False); - xw.netwmiconname = XInternAtom(xw.dpy, "_NET_WM_ICON_NAME", False); - XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1); - - xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False); - XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32, - PropModeReplace, (uchar *)&thispid, 1); - - win.mode = MODE_NUMLOCK; - resettitle(); - xhints(); - XMapWindow(xw.dpy, xw.win); - XSync(xw.dpy, False); - - clock_gettime(CLOCK_MONOTONIC, &xsel.tclick1); - clock_gettime(CLOCK_MONOTONIC, &xsel.tclick2); - xsel.primary = NULL; - xsel.clipboard = NULL; - xsel.xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0); - if (xsel.xtarget == None) - xsel.xtarget = XA_STRING; -} - -int -xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) -{ - float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp; - ushort mode, prevmode = USHRT_MAX; - Font *font = &dc.font; - int frcflags = FRC_NORMAL; - float runewidth = win.cw; - Rune rune; - FT_UInt glyphidx; - FcResult fcres; - FcPattern *fcpattern, *fontpattern; - FcFontSet *fcsets[] = { NULL }; - FcCharSet *fccharset; - int i, f, numspecs = 0; - - for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) { - /* Fetch rune and mode for current glyph. */ - rune = glyphs[i].u; - mode = glyphs[i].mode; - - /* Skip dummy wide-character spacing. */ - if (mode == ATTR_WDUMMY) - continue; - - /* Determine font for glyph if different from previous glyph. */ - if (prevmode != mode) { - prevmode = mode; - font = &dc.font; - frcflags = FRC_NORMAL; - runewidth = win.cw * ((mode & ATTR_WIDE) ? 2.0f : 1.0f); - if ((mode & ATTR_ITALIC) && (mode & ATTR_BOLD)) { - font = &dc.ibfont; - frcflags = FRC_ITALICBOLD; - } else if (mode & ATTR_ITALIC) { - font = &dc.ifont; - frcflags = FRC_ITALIC; - } else if (mode & ATTR_BOLD) { - font = &dc.bfont; - frcflags = FRC_BOLD; - } - yp = winy + font->ascent; - } - - /* Lookup character index with default font. */ - glyphidx = XftCharIndex(xw.dpy, font->match, rune); - if (glyphidx) { - specs[numspecs].font = font->match; - specs[numspecs].glyph = glyphidx; - specs[numspecs].x = (short)xp; - specs[numspecs].y = (short)yp; - xp += runewidth; - numspecs++; - continue; - } - - /* Fallback on font cache, search the font cache for match. */ - for (f = 0; f < frclen; f++) { - glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune); - /* Everything correct. */ - if (glyphidx && frc[f].flags == frcflags) - break; - /* We got a default font for a not found glyph. */ - if (!glyphidx && frc[f].flags == frcflags - && frc[f].unicodep == rune) { - break; - } - } - - /* Nothing was found. Use fontconfig to find matching font. */ - if (f >= frclen) { - if (!font->set) - font->set = FcFontSort(0, font->pattern, - 1, 0, &fcres); - fcsets[0] = font->set; - - /* - * Nothing was found in the cache. Now use - * some dozen of Fontconfig calls to get the - * font for one single character. - * - * Xft and fontconfig are design failures. - */ - fcpattern = FcPatternDuplicate(font->pattern); - fccharset = FcCharSetCreate(); - - FcCharSetAddChar(fccharset, rune); - FcPatternAddCharSet(fcpattern, FC_CHARSET, - fccharset); - FcPatternAddBool(fcpattern, FC_SCALABLE, 1); - - FcConfigSubstitute(0, fcpattern, - FcMatchPattern); - FcDefaultSubstitute(fcpattern); - - fontpattern = FcFontSetMatch(0, fcsets, 1, - fcpattern, &fcres); - - /* Allocate memory for the new cache entry. */ - if (frclen >= frccap) { - frccap += 16; - frc = xrealloc(frc, frccap * sizeof(Fontcache)); - } - - frc[frclen].font = XftFontOpenPattern(xw.dpy, - fontpattern); - if (!frc[frclen].font) - die("XftFontOpenPattern failed seeking fallback font: %s\n", - strerror(errno)); - frc[frclen].flags = frcflags; - frc[frclen].unicodep = rune; - - glyphidx = XftCharIndex(xw.dpy, frc[frclen].font, rune); - - f = frclen; - frclen++; - - FcPatternDestroy(fcpattern); - FcCharSetDestroy(fccharset); - } - - specs[numspecs].font = frc[f].font; - specs[numspecs].glyph = glyphidx; - specs[numspecs].x = (short)xp; - specs[numspecs].y = (short)yp; - xp += runewidth; - numspecs++; - } - - return numspecs; -} - -void -xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y) -{ - int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); - int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, - width = charlen * win.cw; - Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; - XRenderColor colfg, colbg; - XRectangle r; - - /* Fallback on color display for attributes not supported by the font */ - if (base.mode & ATTR_ITALIC && base.mode & ATTR_BOLD) { - if (dc.ibfont.badslant || dc.ibfont.badweight) - base.fg = defaultattr; - } else if ((base.mode & ATTR_ITALIC && dc.ifont.badslant) || - (base.mode & ATTR_BOLD && dc.bfont.badweight)) { - base.fg = defaultattr; - } - - if (IS_TRUECOL(base.fg)) { - colfg.alpha = 0xffff; - colfg.red = TRUERED(base.fg); - colfg.green = TRUEGREEN(base.fg); - colfg.blue = TRUEBLUE(base.fg); - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &truefg); - fg = &truefg; - } else { - fg = &dc.col[base.fg]; - } - - if (IS_TRUECOL(base.bg)) { - colbg.alpha = 0xffff; - colbg.green = TRUEGREEN(base.bg); - colbg.red = TRUERED(base.bg); - colbg.blue = TRUEBLUE(base.bg); - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, &truebg); - bg = &truebg; - } else { - bg = &dc.col[base.bg]; - } - - /* Change basic system colors [0-7] to bright system colors [8-15] */ - if ((base.mode & ATTR_BOLD_FAINT) == ATTR_BOLD && BETWEEN(base.fg, 0, 7)) - fg = &dc.col[base.fg + 8]; - - if (IS_SET(MODE_REVERSE)) { - if (fg == &dc.col[defaultfg]) { - fg = &dc.col[defaultbg]; - } else { - colfg.red = ~fg->color.red; - colfg.green = ~fg->color.green; - colfg.blue = ~fg->color.blue; - colfg.alpha = fg->color.alpha; - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, - &revfg); - fg = &revfg; - } - - if (bg == &dc.col[defaultbg]) { - bg = &dc.col[defaultfg]; - } else { - colbg.red = ~bg->color.red; - colbg.green = ~bg->color.green; - colbg.blue = ~bg->color.blue; - colbg.alpha = bg->color.alpha; - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, - &revbg); - bg = &revbg; - } - } - - if ((base.mode & ATTR_BOLD_FAINT) == ATTR_FAINT) { - colfg.red = fg->color.red / 2; - colfg.green = fg->color.green / 2; - colfg.blue = fg->color.blue / 2; - colfg.alpha = fg->color.alpha; - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &revfg); - fg = &revfg; - } - - if (base.mode & ATTR_REVERSE) { - temp = fg; - fg = bg; - bg = temp; - } - - if (base.mode & ATTR_BLINK && win.mode & MODE_BLINK) - fg = bg; - - if (base.mode & ATTR_INVISIBLE) - fg = bg; - - /* Intelligent cleaning up of the borders. */ - if (x == 0) { - xclear(0, (y == 0)? 0 : winy, borderpx, - winy + win.ch + - ((winy + win.ch >= borderpx + win.th)? win.h : 0)); - } - if (winx + width >= borderpx + win.tw) { - xclear(winx + width, (y == 0)? 0 : winy, win.w, - ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch))); - } - if (y == 0) - xclear(winx, 0, winx + width, borderpx); - if (winy + win.ch >= borderpx + win.th) - xclear(winx, winy + win.ch, winx + width, win.h); - - /* Clean up the region we want to draw to. */ - XftDrawRect(xw.draw, bg, winx, winy, width, win.ch); - - /* Set the clip region because Xft is sometimes dirty. */ - r.x = 0; - r.y = 0; - r.height = win.ch; - r.width = width; - XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1); - - /* Render the glyphs. */ - XftDrawGlyphFontSpec(xw.draw, fg, specs, len); - - /* Render underline and strikethrough. */ - if (base.mode & ATTR_UNDERLINE) { - XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1, - width, 1); - } - - if (base.mode & ATTR_STRUCK) { - XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3, - width, 1); - } - - /* Reset clip to none. */ - XftDrawSetClip(xw.draw, 0); -} - -void -xdrawglyph(Glyph g, int x, int y) -{ - int numspecs; - XftGlyphFontSpec spec; - - numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y); - xdrawglyphfontspecs(&spec, g, numspecs, x, y); -} - -void -xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) -{ - Color drawcol; - - /* remove the old cursor */ - if (selected(ox, oy)) - og.mode ^= ATTR_REVERSE; - xdrawglyph(og, ox, oy); - - if (IS_SET(MODE_HIDE)) - return; - - /* - * Select the right color for the right mode. - */ - g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE; - - if (IS_SET(MODE_REVERSE)) { - g.mode |= ATTR_REVERSE; - g.bg = defaultfg; - if (selected(cx, cy)) { - drawcol = dc.col[defaultcs]; - g.fg = defaultrcs; - } else { - drawcol = dc.col[defaultrcs]; - g.fg = defaultcs; - } - } else { - if (selected(cx, cy)) { - g.fg = defaultfg; - g.bg = defaultrcs; - } else { - g.fg = defaultbg; - g.bg = defaultcs; - } - drawcol = dc.col[g.bg]; - } - - /* draw the new one */ - if (IS_SET(MODE_FOCUSED)) { - switch (win.cursor) { - case 7: /* st extension */ - g.u = 0x2603; /* snowman (U+2603) */ - /* FALLTHROUGH */ - case 0: /* Blinking Block */ - case 1: /* Blinking Block (Default) */ - case 2: /* Steady Block */ - xdrawglyph(g, cx, cy); - break; - case 3: /* Blinking Underline */ - case 4: /* Steady Underline */ - XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + (cy + 1) * win.ch - \ - cursorthickness, - win.cw, cursorthickness); - break; - case 5: /* Blinking bar */ - case 6: /* Steady bar */ - XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + cy * win.ch, - cursorthickness, win.ch); - break; - } - } else { - XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + cy * win.ch, - win.cw - 1, 1); - XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + cy * win.ch, - 1, win.ch - 1); - XftDrawRect(xw.draw, &drawcol, - borderpx + (cx + 1) * win.cw - 1, - borderpx + cy * win.ch, - 1, win.ch - 1); - XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + (cy + 1) * win.ch - 1, - win.cw, 1); - } -} - -void -xsetenv(void) -{ - char buf[sizeof(long) * 8 + 1]; - - snprintf(buf, sizeof(buf), "%lu", xw.win); - setenv("WINDOWID", buf, 1); -} - -void -xseticontitle(char *p) -{ - XTextProperty prop; - DEFAULT(p, opt_title); - - Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, - &prop); - XSetWMIconName(xw.dpy, xw.win, &prop); - XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmiconname); - XFree(prop.value); -} - -void -xsettitle(char *p) -{ - XTextProperty prop; - DEFAULT(p, opt_title); - - Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, - &prop); - XSetWMName(xw.dpy, xw.win, &prop); - XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname); - XFree(prop.value); -} - -int -xstartdraw(void) -{ - return IS_SET(MODE_VISIBLE); -} - -void -xdrawline(Line line, int x1, int y1, int x2) -{ - int i, x, ox, numspecs; - Glyph base, new; - XftGlyphFontSpec *specs = xw.specbuf; - - numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1); - i = ox = 0; - for (x = x1; x < x2 && i < numspecs; x++) { - new = line[x]; - if (new.mode == ATTR_WDUMMY) - continue; - if (selected(x, y1)) - new.mode ^= ATTR_REVERSE; - if (i > 0 && ATTRCMP(base, new)) { - xdrawglyphfontspecs(specs, base, i, ox, y1); - specs += i; - numspecs -= i; - i = 0; - } - if (i == 0) { - ox = x; - base = new; - } - i++; - } - if (i > 0) - xdrawglyphfontspecs(specs, base, i, ox, y1); -} - -void -xfinishdraw(void) -{ - XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, - win.h, 0, 0); - XSetForeground(xw.dpy, dc.gc, - dc.col[IS_SET(MODE_REVERSE)? - defaultfg : defaultbg].pixel); -} - -void -xximspot(int x, int y) -{ - if (xw.ime.xic == NULL) - return; - - xw.ime.spot.x = borderpx + x * win.cw; - xw.ime.spot.y = borderpx + (y + 1) * win.ch; - - XSetICValues(xw.ime.xic, XNPreeditAttributes, xw.ime.spotlist, NULL); -} - -void -expose(XEvent *ev) -{ - redraw(); -} - -void -visibility(XEvent *ev) -{ - XVisibilityEvent *e = &ev->xvisibility; - - MODBIT(win.mode, e->state != VisibilityFullyObscured, MODE_VISIBLE); -} - -void -unmap(XEvent *ev) -{ - win.mode &= ~MODE_VISIBLE; -} - -void -xsetpointermotion(int set) -{ - MODBIT(xw.attrs.event_mask, set, PointerMotionMask); - XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs); -} - -void -xsetmode(int set, unsigned int flags) -{ - int mode = win.mode; - MODBIT(win.mode, set, flags); - if ((win.mode & MODE_REVERSE) != (mode & MODE_REVERSE)) - redraw(); -} - -int -xsetcursor(int cursor) -{ - if (!BETWEEN(cursor, 0, 7)) /* 7: st extension */ - return 1; - win.cursor = cursor; - return 0; -} - -void -xseturgency(int add) -{ - XWMHints *h = XGetWMHints(xw.dpy, xw.win); - - MODBIT(h->flags, add, XUrgencyHint); - XSetWMHints(xw.dpy, xw.win, h); - XFree(h); -} - -void -xbell(void) -{ - if (!(IS_SET(MODE_FOCUSED))) - xseturgency(1); - if (bellvolume) - XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL); -} - -void -focus(XEvent *ev) -{ - XFocusChangeEvent *e = &ev->xfocus; - - if (e->mode == NotifyGrab) - return; - - if (ev->type == FocusIn) { - if (xw.ime.xic) - XSetICFocus(xw.ime.xic); - win.mode |= MODE_FOCUSED; - xseturgency(0); - if (IS_SET(MODE_FOCUS)) - ttywrite("\033[I", 3, 0); - } else { - if (xw.ime.xic) - XUnsetICFocus(xw.ime.xic); - win.mode &= ~MODE_FOCUSED; - if (IS_SET(MODE_FOCUS)) - ttywrite("\033[O", 3, 0); - } -} - -int -match(uint mask, uint state) -{ - return mask == XK_ANY_MOD || mask == (state & ~ignoremod); -} - -char* -kmap(KeySym k, uint state) -{ - Key *kp; - int i; - - /* Check for mapped keys out of X11 function keys. */ - for (i = 0; i < LEN(mappedkeys); i++) { - if (mappedkeys[i] == k) - break; - } - if (i == LEN(mappedkeys)) { - if ((k & 0xFFFF) < 0xFD00) - return NULL; - } - - for (kp = key; kp < key + LEN(key); kp++) { - if (kp->k != k) - continue; - - if (!match(kp->mask, state)) - continue; - - if (IS_SET(MODE_APPKEYPAD) ? kp->appkey < 0 : kp->appkey > 0) - continue; - if (IS_SET(MODE_NUMLOCK) && kp->appkey == 2) - continue; - - if (IS_SET(MODE_APPCURSOR) ? kp->appcursor < 0 : kp->appcursor > 0) - continue; - - return kp->s; - } - - return NULL; -} - -void -kpress(XEvent *ev) -{ - XKeyEvent *e = &ev->xkey; - KeySym ksym; - char buf[64], *customkey; - int len; - Rune c; - Status status; - Shortcut *bp; - - if (IS_SET(MODE_KBDLOCK)) - return; - - if (xw.ime.xic) - len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status); - else - len = XLookupString(e, buf, sizeof buf, &ksym, NULL); - /* 1. shortcuts */ - for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) { - if (ksym == bp->keysym && match(bp->mod, e->state)) { - bp->func(&(bp->arg)); - return; - } - } - - /* 2. custom keys from config.h */ - if ((customkey = kmap(ksym, e->state))) { - ttywrite(customkey, strlen(customkey), 1); - return; - } - - /* 3. composed string from input method */ - if (len == 0) - return; - if (len == 1 && e->state & Mod1Mask) { - if (IS_SET(MODE_8BIT)) { - if (*buf < 0177) { - c = *buf | 0x80; - len = utf8encode(c, buf); - } - } else { - buf[1] = buf[0]; - buf[0] = '\033'; - len = 2; - } - } - ttywrite(buf, len, 1); -} - -void -cmessage(XEvent *e) -{ - /* - * See xembed specs - * http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html - */ - if (e->xclient.message_type == xw.xembed && e->xclient.format == 32) { - if (e->xclient.data.l[1] == XEMBED_FOCUS_IN) { - win.mode |= MODE_FOCUSED; - xseturgency(0); - } else if (e->xclient.data.l[1] == XEMBED_FOCUS_OUT) { - win.mode &= ~MODE_FOCUSED; - } - } else if (e->xclient.data.l[0] == xw.wmdeletewin) { - ttyhangup(); - exit(0); - } -} - -void -resize(XEvent *e) -{ - if (e->xconfigure.width == win.w && e->xconfigure.height == win.h) - return; - - cresize(e->xconfigure.width, e->xconfigure.height); -} - -void -run(void) -{ - XEvent ev; - int w = win.w, h = win.h; - fd_set rfd; - int xfd = XConnectionNumber(xw.dpy), ttyfd, xev, drawing; - struct timespec seltv, *tv, now, lastblink, trigger; - double timeout; - - /* Waiting for window mapping */ - do { - XNextEvent(xw.dpy, &ev); - /* - * This XFilterEvent call is required because of XOpenIM. It - * does filter out the key event and some client message for - * the input method too. - */ - if (XFilterEvent(&ev, None)) - continue; - if (ev.type == ConfigureNotify) { - w = ev.xconfigure.width; - h = ev.xconfigure.height; - } - } while (ev.type != MapNotify); - - ttyfd = ttynew(opt_line, shell, opt_io, opt_cmd); - cresize(w, h); - - for (timeout = -1, drawing = 0, lastblink = (struct timespec){0};;) { - FD_ZERO(&rfd); - FD_SET(ttyfd, &rfd); - FD_SET(xfd, &rfd); - - if (XPending(xw.dpy)) - timeout = 0; /* existing events might not set xfd */ - - seltv.tv_sec = timeout / 1E3; - seltv.tv_nsec = 1E6 * (timeout - 1E3 * seltv.tv_sec); - tv = timeout >= 0 ? &seltv : NULL; - - if (pselect(MAX(xfd, ttyfd)+1, &rfd, NULL, NULL, tv, NULL) < 0) { - if (errno == EINTR) - continue; - die("select failed: %s\n", strerror(errno)); - } - clock_gettime(CLOCK_MONOTONIC, &now); - - if (FD_ISSET(ttyfd, &rfd)) - ttyread(); - - xev = 0; - while (XPending(xw.dpy)) { - xev = 1; - XNextEvent(xw.dpy, &ev); - if (XFilterEvent(&ev, None)) - continue; - if (handler[ev.type]) - (handler[ev.type])(&ev); - } - - /* - * To reduce flicker and tearing, when new content or event - * triggers drawing, we first wait a bit to ensure we got - * everything, and if nothing new arrives - we draw. - * We start with trying to wait minlatency ms. If more content - * arrives sooner, we retry with shorter and shorter periods, - * and eventually draw even without idle after maxlatency ms. - * Typically this results in low latency while interacting, - * maximum latency intervals during `cat huge.txt`, and perfect - * sync with periodic updates from animations/key-repeats/etc. - */ - if (FD_ISSET(ttyfd, &rfd) || xev) { - if (!drawing) { - trigger = now; - drawing = 1; - } - timeout = (maxlatency - TIMEDIFF(now, trigger)) \ - / maxlatency * minlatency; - if (timeout > 0) - continue; /* we have time, try to find idle */ - } - - /* idle detected or maxlatency exhausted -> draw */ - timeout = -1; - if (blinktimeout && tattrset(ATTR_BLINK)) { - timeout = blinktimeout - TIMEDIFF(now, lastblink); - if (timeout <= 0) { - if (-timeout > blinktimeout) /* start visible */ - win.mode |= MODE_BLINK; - win.mode ^= MODE_BLINK; - tsetdirtattr(ATTR_BLINK); - lastblink = now; - timeout = blinktimeout; - } - } - - draw(); - XFlush(xw.dpy); - drawing = 0; - } -} - -void -usage(void) -{ - die("usage: %s [-aiv] [-c class] [-f font] [-g geometry]" - " [-n name] [-o file]\n" - " [-T title] [-t title] [-w windowid]" - " [[-e] command [args ...]]\n" - " %s [-aiv] [-c class] [-f font] [-g geometry]" - " [-n name] [-o file]\n" - " [-T title] [-t title] [-w windowid] -l line" - " [stty_args ...]\n", argv0, argv0); -} - -int -main(int argc, char *argv[]) -{ - xw.l = xw.t = 0; - xw.isfixed = False; - xsetcursor(cursorshape); - - ARGBEGIN { - case 'a': - allowaltscreen = 0; - break; - case 'c': - opt_class = EARGF(usage()); - break; - case 'e': - if (argc > 0) - --argc, ++argv; - goto run; - case 'f': - opt_font = EARGF(usage()); - break; - case 'g': - xw.gm = XParseGeometry(EARGF(usage()), - &xw.l, &xw.t, &cols, &rows); - break; - case 'i': - xw.isfixed = 1; - break; - case 'o': - opt_io = EARGF(usage()); - break; - case 'l': - opt_line = EARGF(usage()); - break; - case 'n': - opt_name = EARGF(usage()); - break; - case 't': - case 'T': - opt_title = EARGF(usage()); - break; - case 'w': - opt_embed = EARGF(usage()); - break; - case 'v': - die("%s " VERSION "\n", argv0); - break; - default: - usage(); - } ARGEND; - -run: - if (argc > 0) /* eat all remaining arguments */ - opt_cmd = argv; - - if (!opt_title) - opt_title = (opt_line || !opt_cmd) ? "st" : opt_cmd[0]; - - setlocale(LC_CTYPE, ""); - XSetLocaleModifiers(""); - cols = MAX(cols, 1); - rows = MAX(rows, 1); - tnew(cols, rows); - xinit(cols, rows); - xsetenv(); - selinit(); - run(); - - return 0; -} diff --git a/st/x.c.orig b/st/x.c.orig deleted file mode 100644 index 120e495..0000000 --- a/st/x.c.orig +++ /dev/null @@ -1,2063 +0,0 @@ -/* See LICENSE for license details. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -char *argv0; -#include "arg.h" -#include "st.h" -#include "win.h" - -/* types used in config.h */ -typedef struct { - uint mod; - KeySym keysym; - void (*func)(const Arg *); - const Arg arg; -} Shortcut; - -typedef struct { - uint mod; - uint button; - void (*func)(const Arg *); - const Arg arg; - uint release; -} MouseShortcut; - -typedef struct { - KeySym k; - uint mask; - char *s; - /* three-valued logic variables: 0 indifferent, 1 on, -1 off */ - signed char appkey; /* application keypad */ - signed char appcursor; /* application cursor */ -} Key; - -/* X modifiers */ -#define XK_ANY_MOD UINT_MAX -#define XK_NO_MOD 0 -#define XK_SWITCH_MOD (1<<13) - -/* function definitions used in config.h */ -static void clipcopy(const Arg *); -static void clippaste(const Arg *); -static void numlock(const Arg *); -static void selpaste(const Arg *); -static void zoom(const Arg *); -static void zoomabs(const Arg *); -static void zoomreset(const Arg *); -static void ttysend(const Arg *); - -/* config.h for applying patches and the configuration. */ -#include "config.h" - -/* XEMBED messages */ -#define XEMBED_FOCUS_IN 4 -#define XEMBED_FOCUS_OUT 5 - -/* macros */ -#define IS_SET(flag) ((win.mode & (flag)) != 0) -#define TRUERED(x) (((x) & 0xff0000) >> 8) -#define TRUEGREEN(x) (((x) & 0xff00)) -#define TRUEBLUE(x) (((x) & 0xff) << 8) - -typedef XftDraw *Draw; -typedef XftColor Color; -typedef XftGlyphFontSpec GlyphFontSpec; - -/* Purely graphic info */ -typedef struct { - int tw, th; /* tty width and height */ - int w, h; /* window width and height */ - int ch; /* char height */ - int cw; /* char width */ - int mode; /* window state/mode flags */ - int cursor; /* cursor style */ -} TermWindow; - -typedef struct { - Display *dpy; - Colormap cmap; - Window win; - Drawable buf; - GlyphFontSpec *specbuf; /* font spec buffer used for rendering */ - Atom xembed, wmdeletewin, netwmname, netwmiconname, netwmpid; - struct { - XIM xim; - XIC xic; - XPoint spot; - XVaNestedList spotlist; - } ime; - Draw draw; - Visual *vis; - XSetWindowAttributes attrs; - int scr; - int isfixed; /* is fixed geometry? */ - int l, t; /* left and top offset */ - int gm; /* geometry mask */ -} XWindow; - -typedef struct { - Atom xtarget; - char *primary, *clipboard; - struct timespec tclick1; - struct timespec tclick2; -} XSelection; - -/* Font structure */ -#define Font Font_ -typedef struct { - int height; - int width; - int ascent; - int descent; - int badslant; - int badweight; - short lbearing; - short rbearing; - XftFont *match; - FcFontSet *set; - FcPattern *pattern; -} Font; - -/* Drawing Context */ -typedef struct { - Color *col; - size_t collen; - Font font, bfont, ifont, ibfont; - GC gc; -} DC; - -static inline ushort sixd_to_16bit(int); -static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int); -static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int); -static void xdrawglyph(Glyph, int, int); -static void xclear(int, int, int, int); -static int xgeommasktogravity(int); -static int ximopen(Display *); -static void ximinstantiate(Display *, XPointer, XPointer); -static void ximdestroy(XIM, XPointer, XPointer); -static int xicdestroy(XIC, XPointer, XPointer); -static void xinit(int, int); -static void cresize(int, int); -static void xresize(int, int); -static void xhints(void); -static int xloadcolor(int, const char *, Color *); -static int xloadfont(Font *, FcPattern *); -static void xloadfonts(char *, double); -static void xunloadfont(Font *); -static void xunloadfonts(void); -static void xsetenv(void); -static void xseturgency(int); -static int evcol(XEvent *); -static int evrow(XEvent *); - -static void expose(XEvent *); -static void visibility(XEvent *); -static void unmap(XEvent *); -static void kpress(XEvent *); -static void cmessage(XEvent *); -static void resize(XEvent *); -static void focus(XEvent *); -static uint buttonmask(uint); -static int mouseaction(XEvent *, uint); -static void brelease(XEvent *); -static void bpress(XEvent *); -static void bmotion(XEvent *); -static void propnotify(XEvent *); -static void selnotify(XEvent *); -static void selclear_(XEvent *); -static void selrequest(XEvent *); -static void setsel(char *, Time); -static void mousesel(XEvent *, int); -static void mousereport(XEvent *); -static char *kmap(KeySym, uint); -static int match(uint, uint); - -static void run(void); -static void usage(void); - -static void (*handler[LASTEvent])(XEvent *) = { - [KeyPress] = kpress, - [ClientMessage] = cmessage, - [ConfigureNotify] = resize, - [VisibilityNotify] = visibility, - [UnmapNotify] = unmap, - [Expose] = expose, - [FocusIn] = focus, - [FocusOut] = focus, - [MotionNotify] = bmotion, - [ButtonPress] = bpress, - [ButtonRelease] = brelease, -/* - * Uncomment if you want the selection to disappear when you select something - * different in another window. - */ -/* [SelectionClear] = selclear_, */ - [SelectionNotify] = selnotify, -/* - * PropertyNotify is only turned on when there is some INCR transfer happening - * for the selection retrieval. - */ - [PropertyNotify] = propnotify, - [SelectionRequest] = selrequest, -}; - -/* Globals */ -static DC dc; -static XWindow xw; -static XSelection xsel; -static TermWindow win; - -/* Font Ring Cache */ -enum { - FRC_NORMAL, - FRC_ITALIC, - FRC_BOLD, - FRC_ITALICBOLD -}; - -typedef struct { - XftFont *font; - int flags; - Rune unicodep; -} Fontcache; - -/* Fontcache is an array now. A new font will be appended to the array. */ -static Fontcache *frc = NULL; -static int frclen = 0; -static int frccap = 0; -static char *usedfont = NULL; -static double usedfontsize = 0; -static double defaultfontsize = 0; - -static char *opt_class = NULL; -static char **opt_cmd = NULL; -static char *opt_embed = NULL; -static char *opt_font = NULL; -static char *opt_io = NULL; -static char *opt_line = NULL; -static char *opt_name = NULL; -static char *opt_title = NULL; - -static int oldbutton = 3; /* button event on startup: 3 = release */ - -void -clipcopy(const Arg *dummy) -{ - Atom clipboard; - - free(xsel.clipboard); - xsel.clipboard = NULL; - - if (xsel.primary != NULL) { - xsel.clipboard = xstrdup(xsel.primary); - clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); - XSetSelectionOwner(xw.dpy, clipboard, xw.win, CurrentTime); - } -} - -void -clippaste(const Arg *dummy) -{ - Atom clipboard; - - clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); - XConvertSelection(xw.dpy, clipboard, xsel.xtarget, clipboard, - xw.win, CurrentTime); -} - -void -selpaste(const Arg *dummy) -{ - XConvertSelection(xw.dpy, XA_PRIMARY, xsel.xtarget, XA_PRIMARY, - xw.win, CurrentTime); -} - -void -numlock(const Arg *dummy) -{ - win.mode ^= MODE_NUMLOCK; -} - -void -zoom(const Arg *arg) -{ - Arg larg; - - larg.f = usedfontsize + arg->f; - zoomabs(&larg); -} - -void -zoomabs(const Arg *arg) -{ - xunloadfonts(); - xloadfonts(usedfont, arg->f); - cresize(0, 0); - redraw(); - xhints(); -} - -void -zoomreset(const Arg *arg) -{ - Arg larg; - - if (defaultfontsize > 0) { - larg.f = defaultfontsize; - zoomabs(&larg); - } -} - -void -ttysend(const Arg *arg) -{ - ttywrite(arg->s, strlen(arg->s), 1); -} - -int -evcol(XEvent *e) -{ - int x = e->xbutton.x - borderpx; - LIMIT(x, 0, win.tw - 1); - return x / win.cw; -} - -int -evrow(XEvent *e) -{ - int y = e->xbutton.y - borderpx; - LIMIT(y, 0, win.th - 1); - return y / win.ch; -} - -void -mousesel(XEvent *e, int done) -{ - int type, seltype = SEL_REGULAR; - uint state = e->xbutton.state & ~(Button1Mask | forcemousemod); - - for (type = 1; type < LEN(selmasks); ++type) { - if (match(selmasks[type], state)) { - seltype = type; - break; - } - } - selextend(evcol(e), evrow(e), seltype, done); - if (done) - setsel(getsel(), e->xbutton.time); -} - -void -mousereport(XEvent *e) -{ - int len, x = evcol(e), y = evrow(e), - button = e->xbutton.button, state = e->xbutton.state; - char buf[40]; - static int ox, oy; - - /* from urxvt */ - if (e->xbutton.type == MotionNotify) { - if (x == ox && y == oy) - return; - if (!IS_SET(MODE_MOUSEMOTION) && !IS_SET(MODE_MOUSEMANY)) - return; - /* MOUSE_MOTION: no reporting if no button is pressed */ - if (IS_SET(MODE_MOUSEMOTION) && oldbutton == 3) - return; - - button = oldbutton + 32; - ox = x; - oy = y; - } else { - if (!IS_SET(MODE_MOUSESGR) && e->xbutton.type == ButtonRelease) { - button = 3; - } else { - button -= Button1; - if (button >= 3) - button += 64 - 3; - } - if (e->xbutton.type == ButtonPress) { - oldbutton = button; - ox = x; - oy = y; - } else if (e->xbutton.type == ButtonRelease) { - oldbutton = 3; - /* MODE_MOUSEX10: no button release reporting */ - if (IS_SET(MODE_MOUSEX10)) - return; - if (button == 64 || button == 65) - return; - } - } - - if (!IS_SET(MODE_MOUSEX10)) { - button += ((state & ShiftMask ) ? 4 : 0) - + ((state & Mod4Mask ) ? 8 : 0) - + ((state & ControlMask) ? 16 : 0); - } - - if (IS_SET(MODE_MOUSESGR)) { - len = snprintf(buf, sizeof(buf), "\033[<%d;%d;%d%c", - button, x+1, y+1, - e->xbutton.type == ButtonRelease ? 'm' : 'M'); - } else if (x < 223 && y < 223) { - len = snprintf(buf, sizeof(buf), "\033[M%c%c%c", - 32+button, 32+x+1, 32+y+1); - } else { - return; - } - - ttywrite(buf, len, 0); -} - -uint -buttonmask(uint button) -{ - return button == Button1 ? Button1Mask - : button == Button2 ? Button2Mask - : button == Button3 ? Button3Mask - : button == Button4 ? Button4Mask - : button == Button5 ? Button5Mask - : 0; -} - -int -mouseaction(XEvent *e, uint release) -{ - MouseShortcut *ms; - - /* ignore Buttonmask for Button - it's set on release */ - uint state = e->xbutton.state & ~buttonmask(e->xbutton.button); - - for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) { - if (ms->release == release && - ms->button == e->xbutton.button && - (match(ms->mod, state) || /* exact or forced */ - match(ms->mod, state & ~forcemousemod))) { - ms->func(&(ms->arg)); - return 1; - } - } - - return 0; -} - -void -bpress(XEvent *e) -{ - struct timespec now; - int snap; - - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { - mousereport(e); - return; - } - - if (mouseaction(e, 0)) - return; - - if (e->xbutton.button == Button1) { - /* - * If the user clicks below predefined timeouts specific - * snapping behaviour is exposed. - */ - clock_gettime(CLOCK_MONOTONIC, &now); - if (TIMEDIFF(now, xsel.tclick2) <= tripleclicktimeout) { - snap = SNAP_LINE; - } else if (TIMEDIFF(now, xsel.tclick1) <= doubleclicktimeout) { - snap = SNAP_WORD; - } else { - snap = 0; - } - xsel.tclick2 = xsel.tclick1; - xsel.tclick1 = now; - - selstart(evcol(e), evrow(e), snap); - } -} - -void -propnotify(XEvent *e) -{ - XPropertyEvent *xpev; - Atom clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); - - xpev = &e->xproperty; - if (xpev->state == PropertyNewValue && - (xpev->atom == XA_PRIMARY || - xpev->atom == clipboard)) { - selnotify(e); - } -} - -void -selnotify(XEvent *e) -{ - ulong nitems, ofs, rem; - int format; - uchar *data, *last, *repl; - Atom type, incratom, property = None; - - incratom = XInternAtom(xw.dpy, "INCR", 0); - - ofs = 0; - if (e->type == SelectionNotify) - property = e->xselection.property; - else if (e->type == PropertyNotify) - property = e->xproperty.atom; - - if (property == None) - return; - - do { - if (XGetWindowProperty(xw.dpy, xw.win, property, ofs, - BUFSIZ/4, False, AnyPropertyType, - &type, &format, &nitems, &rem, - &data)) { - fprintf(stderr, "Clipboard allocation failed\n"); - return; - } - - if (e->type == PropertyNotify && nitems == 0 && rem == 0) { - /* - * If there is some PropertyNotify with no data, then - * this is the signal of the selection owner that all - * data has been transferred. We won't need to receive - * PropertyNotify events anymore. - */ - MODBIT(xw.attrs.event_mask, 0, PropertyChangeMask); - XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, - &xw.attrs); - } - - if (type == incratom) { - /* - * Activate the PropertyNotify events so we receive - * when the selection owner does send us the next - * chunk of data. - */ - MODBIT(xw.attrs.event_mask, 1, PropertyChangeMask); - XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, - &xw.attrs); - - /* - * Deleting the property is the transfer start signal. - */ - XDeleteProperty(xw.dpy, xw.win, (int)property); - continue; - } - - /* - * As seen in getsel: - * Line endings are inconsistent in the terminal and GUI world - * copy and pasting. When receiving some selection data, - * replace all '\n' with '\r'. - * FIXME: Fix the computer world. - */ - repl = data; - last = data + nitems * format / 8; - while ((repl = memchr(repl, '\n', last - repl))) { - *repl++ = '\r'; - } - - if (IS_SET(MODE_BRCKTPASTE) && ofs == 0) - ttywrite("\033[200~", 6, 0); - ttywrite((char *)data, nitems * format / 8, 1); - if (IS_SET(MODE_BRCKTPASTE) && rem == 0) - ttywrite("\033[201~", 6, 0); - XFree(data); - /* number of 32-bit chunks returned */ - ofs += nitems * format / 32; - } while (rem > 0); - - /* - * Deleting the property again tells the selection owner to send the - * next data chunk in the property. - */ - XDeleteProperty(xw.dpy, xw.win, (int)property); -} - -void -xclipcopy(void) -{ - clipcopy(NULL); -} - -void -selclear_(XEvent *e) -{ - selclear(); -} - -void -selrequest(XEvent *e) -{ - XSelectionRequestEvent *xsre; - XSelectionEvent xev; - Atom xa_targets, string, clipboard; - char *seltext; - - xsre = (XSelectionRequestEvent *) e; - xev.type = SelectionNotify; - xev.requestor = xsre->requestor; - xev.selection = xsre->selection; - xev.target = xsre->target; - xev.time = xsre->time; - if (xsre->property == None) - xsre->property = xsre->target; - - /* reject */ - xev.property = None; - - xa_targets = XInternAtom(xw.dpy, "TARGETS", 0); - if (xsre->target == xa_targets) { - /* respond with the supported type */ - string = xsel.xtarget; - XChangeProperty(xsre->display, xsre->requestor, xsre->property, - XA_ATOM, 32, PropModeReplace, - (uchar *) &string, 1); - xev.property = xsre->property; - } else if (xsre->target == xsel.xtarget || xsre->target == XA_STRING) { - /* - * xith XA_STRING non ascii characters may be incorrect in the - * requestor. It is not our problem, use utf8. - */ - clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); - if (xsre->selection == XA_PRIMARY) { - seltext = xsel.primary; - } else if (xsre->selection == clipboard) { - seltext = xsel.clipboard; - } else { - fprintf(stderr, - "Unhandled clipboard selection 0x%lx\n", - xsre->selection); - return; - } - if (seltext != NULL) { - XChangeProperty(xsre->display, xsre->requestor, - xsre->property, xsre->target, - 8, PropModeReplace, - (uchar *)seltext, strlen(seltext)); - xev.property = xsre->property; - } - } - - /* all done, send a notification to the listener */ - if (!XSendEvent(xsre->display, xsre->requestor, 1, 0, (XEvent *) &xev)) - fprintf(stderr, "Error sending SelectionNotify event\n"); -} - -void -setsel(char *str, Time t) -{ - if (!str) - return; - - free(xsel.primary); - xsel.primary = str; - - XSetSelectionOwner(xw.dpy, XA_PRIMARY, xw.win, t); - if (XGetSelectionOwner(xw.dpy, XA_PRIMARY) != xw.win) - selclear(); -} - -void -xsetsel(char *str) -{ - setsel(str, CurrentTime); -} - -void -brelease(XEvent *e) -{ - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { - mousereport(e); - return; - } - - if (mouseaction(e, 1)) - return; - if (e->xbutton.button == Button1) - mousesel(e, 1); -} - -void -bmotion(XEvent *e) -{ - if (IS_SET(MODE_MOUSE) && !(e->xbutton.state & forcemousemod)) { - mousereport(e); - return; - } - - mousesel(e, 0); -} - -void -cresize(int width, int height) -{ - int col, row; - - if (width != 0) - win.w = width; - if (height != 0) - win.h = height; - - col = (win.w - 2 * borderpx) / win.cw; - row = (win.h - 2 * borderpx) / win.ch; - col = MAX(1, col); - row = MAX(1, row); - - tresize(col, row); - xresize(col, row); - ttyresize(win.tw, win.th); -} - -void -xresize(int col, int row) -{ - win.tw = col * win.cw; - win.th = row * win.ch; - - XFreePixmap(xw.dpy, xw.buf); - xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, - DefaultDepth(xw.dpy, xw.scr)); - XftDrawChange(xw.draw, xw.buf); - xclear(0, 0, win.w, win.h); - - /* resize to new width */ - xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec)); -} - -ushort -sixd_to_16bit(int x) -{ - return x == 0 ? 0 : 0x3737 + 0x2828 * x; -} - -int -xloadcolor(int i, const char *name, Color *ncolor) -{ - XRenderColor color = { .alpha = 0xffff }; - - if (!name) { - if (BETWEEN(i, 16, 255)) { /* 256 color */ - if (i < 6*6*6+16) { /* same colors as xterm */ - color.red = sixd_to_16bit( ((i-16)/36)%6 ); - color.green = sixd_to_16bit( ((i-16)/6) %6 ); - color.blue = sixd_to_16bit( ((i-16)/1) %6 ); - } else { /* greyscale */ - color.red = 0x0808 + 0x0a0a * (i - (6*6*6+16)); - color.green = color.blue = color.red; - } - return XftColorAllocValue(xw.dpy, xw.vis, - xw.cmap, &color, ncolor); - } else - name = colorname[i]; - } - - return XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, ncolor); -} - -void -xloadcols(void) -{ - int i; - static int loaded; - Color *cp; - - if (loaded) { - for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp) - XftColorFree(xw.dpy, xw.vis, xw.cmap, cp); - } else { - dc.collen = MAX(LEN(colorname), 256); - dc.col = xmalloc(dc.collen * sizeof(Color)); - } - - for (i = 0; i < dc.collen; i++) - if (!xloadcolor(i, NULL, &dc.col[i])) { - if (colorname[i]) - die("could not allocate color '%s'\n", colorname[i]); - else - die("could not allocate color %d\n", i); - } - loaded = 1; -} - -int -xsetcolorname(int x, const char *name) -{ - Color ncolor; - - if (!BETWEEN(x, 0, dc.collen)) - return 1; - - if (!xloadcolor(x, name, &ncolor)) - return 1; - - XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]); - dc.col[x] = ncolor; - - return 0; -} - -/* - * Absolute coordinates. - */ -void -xclear(int x1, int y1, int x2, int y2) -{ - XftDrawRect(xw.draw, - &dc.col[IS_SET(MODE_REVERSE)? defaultfg : defaultbg], - x1, y1, x2-x1, y2-y1); -} - -void -xhints(void) -{ - XClassHint class = {opt_name ? opt_name : termname, - opt_class ? opt_class : termname}; - XWMHints wm = {.flags = InputHint, .input = 1}; - XSizeHints *sizeh; - - sizeh = XAllocSizeHints(); - - sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize; - sizeh->height = win.h; - sizeh->width = win.w; - sizeh->height_inc = win.ch; - sizeh->width_inc = win.cw; - sizeh->base_height = 2 * borderpx; - sizeh->base_width = 2 * borderpx; - sizeh->min_height = win.ch + 2 * borderpx; - sizeh->min_width = win.cw + 2 * borderpx; - if (xw.isfixed) { - sizeh->flags |= PMaxSize; - sizeh->min_width = sizeh->max_width = win.w; - sizeh->min_height = sizeh->max_height = win.h; - } - if (xw.gm & (XValue|YValue)) { - sizeh->flags |= USPosition | PWinGravity; - sizeh->x = xw.l; - sizeh->y = xw.t; - sizeh->win_gravity = xgeommasktogravity(xw.gm); - } - - XSetWMProperties(xw.dpy, xw.win, NULL, NULL, NULL, 0, sizeh, &wm, - &class); - XFree(sizeh); -} - -int -xgeommasktogravity(int mask) -{ - switch (mask & (XNegative|YNegative)) { - case 0: - return NorthWestGravity; - case XNegative: - return NorthEastGravity; - case YNegative: - return SouthWestGravity; - } - - return SouthEastGravity; -} - -int -xloadfont(Font *f, FcPattern *pattern) -{ - FcPattern *configured; - FcPattern *match; - FcResult result; - XGlyphInfo extents; - int wantattr, haveattr; - - /* - * Manually configure instead of calling XftMatchFont - * so that we can use the configured pattern for - * "missing glyph" lookups. - */ - configured = FcPatternDuplicate(pattern); - if (!configured) - return 1; - - FcConfigSubstitute(NULL, configured, FcMatchPattern); - XftDefaultSubstitute(xw.dpy, xw.scr, configured); - - match = FcFontMatch(NULL, configured, &result); - if (!match) { - FcPatternDestroy(configured); - return 1; - } - - if (!(f->match = XftFontOpenPattern(xw.dpy, match))) { - FcPatternDestroy(configured); - FcPatternDestroy(match); - return 1; - } - - if ((XftPatternGetInteger(pattern, "slant", 0, &wantattr) == - XftResultMatch)) { - /* - * Check if xft was unable to find a font with the appropriate - * slant but gave us one anyway. Try to mitigate. - */ - if ((XftPatternGetInteger(f->match->pattern, "slant", 0, - &haveattr) != XftResultMatch) || haveattr < wantattr) { - f->badslant = 1; - fputs("font slant does not match\n", stderr); - } - } - - if ((XftPatternGetInteger(pattern, "weight", 0, &wantattr) == - XftResultMatch)) { - if ((XftPatternGetInteger(f->match->pattern, "weight", 0, - &haveattr) != XftResultMatch) || haveattr != wantattr) { - f->badweight = 1; - fputs("font weight does not match\n", stderr); - } - } - - XftTextExtentsUtf8(xw.dpy, f->match, - (const FcChar8 *) ascii_printable, - strlen(ascii_printable), &extents); - - f->set = NULL; - f->pattern = configured; - - f->ascent = f->match->ascent; - f->descent = f->match->descent; - f->lbearing = 0; - f->rbearing = f->match->max_advance_width; - - f->height = f->ascent + f->descent; - f->width = DIVCEIL(extents.xOff, strlen(ascii_printable)); - - return 0; -} - -void -xloadfonts(char *fontstr, double fontsize) -{ - FcPattern *pattern; - double fontval; - - if (fontstr[0] == '-') - pattern = XftXlfdParse(fontstr, False, False); - else - pattern = FcNameParse((FcChar8 *)fontstr); - - if (!pattern) - die("can't open font %s\n", fontstr); - - if (fontsize > 1) { - FcPatternDel(pattern, FC_PIXEL_SIZE); - FcPatternDel(pattern, FC_SIZE); - FcPatternAddDouble(pattern, FC_PIXEL_SIZE, (double)fontsize); - usedfontsize = fontsize; - } else { - if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) == - FcResultMatch) { - usedfontsize = fontval; - } else if (FcPatternGetDouble(pattern, FC_SIZE, 0, &fontval) == - FcResultMatch) { - usedfontsize = -1; - } else { - /* - * Default font size is 12, if none given. This is to - * have a known usedfontsize value. - */ - FcPatternAddDouble(pattern, FC_PIXEL_SIZE, 12); - usedfontsize = 12; - } - defaultfontsize = usedfontsize; - } - - if (xloadfont(&dc.font, pattern)) - die("can't open font %s\n", fontstr); - - if (usedfontsize < 0) { - FcPatternGetDouble(dc.font.match->pattern, - FC_PIXEL_SIZE, 0, &fontval); - usedfontsize = fontval; - if (fontsize == 0) - defaultfontsize = fontval; - } - - /* Setting character width and height. */ - win.cw = ceilf(dc.font.width * cwscale); - win.ch = ceilf(dc.font.height * chscale); - - FcPatternDel(pattern, FC_SLANT); - FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC); - if (xloadfont(&dc.ifont, pattern)) - die("can't open font %s\n", fontstr); - - FcPatternDel(pattern, FC_WEIGHT); - FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD); - if (xloadfont(&dc.ibfont, pattern)) - die("can't open font %s\n", fontstr); - - FcPatternDel(pattern, FC_SLANT); - FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN); - if (xloadfont(&dc.bfont, pattern)) - die("can't open font %s\n", fontstr); - - FcPatternDestroy(pattern); -} - -void -xunloadfont(Font *f) -{ - XftFontClose(xw.dpy, f->match); - FcPatternDestroy(f->pattern); - if (f->set) - FcFontSetDestroy(f->set); -} - -void -xunloadfonts(void) -{ - /* Free the loaded fonts in the font cache. */ - while (frclen > 0) - XftFontClose(xw.dpy, frc[--frclen].font); - - xunloadfont(&dc.font); - xunloadfont(&dc.bfont); - xunloadfont(&dc.ifont); - xunloadfont(&dc.ibfont); -} - -int -ximopen(Display *dpy) -{ - XIMCallback imdestroy = { .client_data = NULL, .callback = ximdestroy }; - XICCallback icdestroy = { .client_data = NULL, .callback = xicdestroy }; - - xw.ime.xim = XOpenIM(xw.dpy, NULL, NULL, NULL); - if (xw.ime.xim == NULL) - return 0; - - if (XSetIMValues(xw.ime.xim, XNDestroyCallback, &imdestroy, NULL)) - fprintf(stderr, "XSetIMValues: " - "Could not set XNDestroyCallback.\n"); - - xw.ime.spotlist = XVaCreateNestedList(0, XNSpotLocation, &xw.ime.spot, - NULL); - - if (xw.ime.xic == NULL) { - xw.ime.xic = XCreateIC(xw.ime.xim, XNInputStyle, - XIMPreeditNothing | XIMStatusNothing, - XNClientWindow, xw.win, - XNDestroyCallback, &icdestroy, - NULL); - } - if (xw.ime.xic == NULL) - fprintf(stderr, "XCreateIC: Could not create input context.\n"); - - return 1; -} - -void -ximinstantiate(Display *dpy, XPointer client, XPointer call) -{ - if (ximopen(dpy)) - XUnregisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, - ximinstantiate, NULL); -} - -void -ximdestroy(XIM xim, XPointer client, XPointer call) -{ - xw.ime.xim = NULL; - XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, - ximinstantiate, NULL); - XFree(xw.ime.spotlist); -} - -int -xicdestroy(XIC xim, XPointer client, XPointer call) -{ - xw.ime.xic = NULL; - return 1; -} - -void -xinit(int cols, int rows) -{ - XGCValues gcvalues; - Cursor cursor; - Window parent; - pid_t thispid = getpid(); - XColor xmousefg, xmousebg; - - if (!(xw.dpy = XOpenDisplay(NULL))) - die("can't open display\n"); - xw.scr = XDefaultScreen(xw.dpy); - xw.vis = XDefaultVisual(xw.dpy, xw.scr); - - /* font */ - if (!FcInit()) - die("could not init fontconfig.\n"); - - usedfont = (opt_font == NULL)? font : opt_font; - xloadfonts(usedfont, 0); - - /* colors */ - xw.cmap = XDefaultColormap(xw.dpy, xw.scr); - xloadcols(); - - /* adjust fixed window geometry */ - win.w = 2 * borderpx + cols * win.cw; - win.h = 2 * borderpx + rows * win.ch; - if (xw.gm & XNegative) - xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2; - if (xw.gm & YNegative) - xw.t += DisplayHeight(xw.dpy, xw.scr) - win.h - 2; - - /* Events */ - xw.attrs.background_pixel = dc.col[defaultbg].pixel; - xw.attrs.border_pixel = dc.col[defaultbg].pixel; - xw.attrs.bit_gravity = NorthWestGravity; - xw.attrs.event_mask = FocusChangeMask | KeyPressMask | KeyReleaseMask - | ExposureMask | VisibilityChangeMask | StructureNotifyMask - | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; - xw.attrs.colormap = xw.cmap; - - if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) - parent = XRootWindow(xw.dpy, xw.scr); - xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t, - win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, - xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity - | CWEventMask | CWColormap, &xw.attrs); - - memset(&gcvalues, 0, sizeof(gcvalues)); - gcvalues.graphics_exposures = False; - dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, - &gcvalues); - xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, - DefaultDepth(xw.dpy, xw.scr)); - XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); - XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); - - /* font spec buffer */ - xw.specbuf = xmalloc(cols * sizeof(GlyphFontSpec)); - - /* Xft rendering context */ - xw.draw = XftDrawCreate(xw.dpy, xw.buf, xw.vis, xw.cmap); - - /* input methods */ - if (!ximopen(xw.dpy)) { - XRegisterIMInstantiateCallback(xw.dpy, NULL, NULL, NULL, - ximinstantiate, NULL); - } - - /* white cursor, black outline */ - cursor = XCreateFontCursor(xw.dpy, mouseshape); - XDefineCursor(xw.dpy, xw.win, cursor); - - if (XParseColor(xw.dpy, xw.cmap, colorname[mousefg], &xmousefg) == 0) { - xmousefg.red = 0xffff; - xmousefg.green = 0xffff; - xmousefg.blue = 0xffff; - } - - if (XParseColor(xw.dpy, xw.cmap, colorname[mousebg], &xmousebg) == 0) { - xmousebg.red = 0x0000; - xmousebg.green = 0x0000; - xmousebg.blue = 0x0000; - } - - XRecolorCursor(xw.dpy, cursor, &xmousefg, &xmousebg); - - xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False); - xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False); - xw.netwmname = XInternAtom(xw.dpy, "_NET_WM_NAME", False); - xw.netwmiconname = XInternAtom(xw.dpy, "_NET_WM_ICON_NAME", False); - XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1); - - xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False); - XChangeProperty(xw.dpy, xw.win, xw.netwmpid, XA_CARDINAL, 32, - PropModeReplace, (uchar *)&thispid, 1); - - win.mode = MODE_NUMLOCK; - resettitle(); - xhints(); - XMapWindow(xw.dpy, xw.win); - XSync(xw.dpy, False); - - clock_gettime(CLOCK_MONOTONIC, &xsel.tclick1); - clock_gettime(CLOCK_MONOTONIC, &xsel.tclick2); - xsel.primary = NULL; - xsel.clipboard = NULL; - xsel.xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0); - if (xsel.xtarget == None) - xsel.xtarget = XA_STRING; -} - -int -xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) -{ - float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp; - ushort mode, prevmode = USHRT_MAX; - Font *font = &dc.font; - int frcflags = FRC_NORMAL; - float runewidth = win.cw; - Rune rune; - FT_UInt glyphidx; - FcResult fcres; - FcPattern *fcpattern, *fontpattern; - FcFontSet *fcsets[] = { NULL }; - FcCharSet *fccharset; - int i, f, numspecs = 0; - - for (i = 0, xp = winx, yp = winy + font->ascent; i < len; ++i) { - /* Fetch rune and mode for current glyph. */ - rune = glyphs[i].u; - mode = glyphs[i].mode; - - /* Skip dummy wide-character spacing. */ - if (mode == ATTR_WDUMMY) - continue; - - /* Determine font for glyph if different from previous glyph. */ - if (prevmode != mode) { - prevmode = mode; - font = &dc.font; - frcflags = FRC_NORMAL; - runewidth = win.cw * ((mode & ATTR_WIDE) ? 2.0f : 1.0f); - if ((mode & ATTR_ITALIC) && (mode & ATTR_BOLD)) { - font = &dc.ibfont; - frcflags = FRC_ITALICBOLD; - } else if (mode & ATTR_ITALIC) { - font = &dc.ifont; - frcflags = FRC_ITALIC; - } else if (mode & ATTR_BOLD) { - font = &dc.bfont; - frcflags = FRC_BOLD; - } - yp = winy + font->ascent; - } - - /* Lookup character index with default font. */ - glyphidx = XftCharIndex(xw.dpy, font->match, rune); - if (glyphidx) { - specs[numspecs].font = font->match; - specs[numspecs].glyph = glyphidx; - specs[numspecs].x = (short)xp; - specs[numspecs].y = (short)yp; - xp += runewidth; - numspecs++; - continue; - } - - /* Fallback on font cache, search the font cache for match. */ - for (f = 0; f < frclen; f++) { - glyphidx = XftCharIndex(xw.dpy, frc[f].font, rune); - /* Everything correct. */ - if (glyphidx && frc[f].flags == frcflags) - break; - /* We got a default font for a not found glyph. */ - if (!glyphidx && frc[f].flags == frcflags - && frc[f].unicodep == rune) { - break; - } - } - - /* Nothing was found. Use fontconfig to find matching font. */ - if (f >= frclen) { - if (!font->set) - font->set = FcFontSort(0, font->pattern, - 1, 0, &fcres); - fcsets[0] = font->set; - - /* - * Nothing was found in the cache. Now use - * some dozen of Fontconfig calls to get the - * font for one single character. - * - * Xft and fontconfig are design failures. - */ - fcpattern = FcPatternDuplicate(font->pattern); - fccharset = FcCharSetCreate(); - - FcCharSetAddChar(fccharset, rune); - FcPatternAddCharSet(fcpattern, FC_CHARSET, - fccharset); - FcPatternAddBool(fcpattern, FC_SCALABLE, 1); - - FcConfigSubstitute(0, fcpattern, - FcMatchPattern); - FcDefaultSubstitute(fcpattern); - - fontpattern = FcFontSetMatch(0, fcsets, 1, - fcpattern, &fcres); - - /* Allocate memory for the new cache entry. */ - if (frclen >= frccap) { - frccap += 16; - frc = xrealloc(frc, frccap * sizeof(Fontcache)); - } - - frc[frclen].font = XftFontOpenPattern(xw.dpy, - fontpattern); - if (!frc[frclen].font) - die("XftFontOpenPattern failed seeking fallback font: %s\n", - strerror(errno)); - frc[frclen].flags = frcflags; - frc[frclen].unicodep = rune; - - glyphidx = XftCharIndex(xw.dpy, frc[frclen].font, rune); - - f = frclen; - frclen++; - - FcPatternDestroy(fcpattern); - FcCharSetDestroy(fccharset); - } - - specs[numspecs].font = frc[f].font; - specs[numspecs].glyph = glyphidx; - specs[numspecs].x = (short)xp; - specs[numspecs].y = (short)yp; - xp += runewidth; - numspecs++; - } - - return numspecs; -} - -void -xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y) -{ - int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); - int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, - width = charlen * win.cw; - Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; - XRenderColor colfg, colbg; - XRectangle r; - - /* Fallback on color display for attributes not supported by the font */ - if (base.mode & ATTR_ITALIC && base.mode & ATTR_BOLD) { - if (dc.ibfont.badslant || dc.ibfont.badweight) - base.fg = defaultattr; - } else if ((base.mode & ATTR_ITALIC && dc.ifont.badslant) || - (base.mode & ATTR_BOLD && dc.bfont.badweight)) { - base.fg = defaultattr; - } - - if (IS_TRUECOL(base.fg)) { - colfg.alpha = 0xffff; - colfg.red = TRUERED(base.fg); - colfg.green = TRUEGREEN(base.fg); - colfg.blue = TRUEBLUE(base.fg); - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &truefg); - fg = &truefg; - } else { - fg = &dc.col[base.fg]; - } - - if (IS_TRUECOL(base.bg)) { - colbg.alpha = 0xffff; - colbg.green = TRUEGREEN(base.bg); - colbg.red = TRUERED(base.bg); - colbg.blue = TRUEBLUE(base.bg); - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, &truebg); - bg = &truebg; - } else { - bg = &dc.col[base.bg]; - } - - /* Change basic system colors [0-7] to bright system colors [8-15] */ - if ((base.mode & ATTR_BOLD_FAINT) == ATTR_BOLD && BETWEEN(base.fg, 0, 7)) - fg = &dc.col[base.fg + 8]; - - if (IS_SET(MODE_REVERSE)) { - if (fg == &dc.col[defaultfg]) { - fg = &dc.col[defaultbg]; - } else { - colfg.red = ~fg->color.red; - colfg.green = ~fg->color.green; - colfg.blue = ~fg->color.blue; - colfg.alpha = fg->color.alpha; - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, - &revfg); - fg = &revfg; - } - - if (bg == &dc.col[defaultbg]) { - bg = &dc.col[defaultfg]; - } else { - colbg.red = ~bg->color.red; - colbg.green = ~bg->color.green; - colbg.blue = ~bg->color.blue; - colbg.alpha = bg->color.alpha; - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, - &revbg); - bg = &revbg; - } - } - - if ((base.mode & ATTR_BOLD_FAINT) == ATTR_FAINT) { - colfg.red = fg->color.red / 2; - colfg.green = fg->color.green / 2; - colfg.blue = fg->color.blue / 2; - colfg.alpha = fg->color.alpha; - XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colfg, &revfg); - fg = &revfg; - } - - if (base.mode & ATTR_REVERSE) { - temp = fg; - fg = bg; - bg = temp; - } - - if (base.mode & ATTR_BLINK && win.mode & MODE_BLINK) - fg = bg; - - if (base.mode & ATTR_INVISIBLE) - fg = bg; - - /* Intelligent cleaning up of the borders. */ - if (x == 0) { - xclear(0, (y == 0)? 0 : winy, borderpx, - winy + win.ch + - ((winy + win.ch >= borderpx + win.th)? win.h : 0)); - } - if (winx + width >= borderpx + win.tw) { - xclear(winx + width, (y == 0)? 0 : winy, win.w, - ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch))); - } - if (y == 0) - xclear(winx, 0, winx + width, borderpx); - if (winy + win.ch >= borderpx + win.th) - xclear(winx, winy + win.ch, winx + width, win.h); - - /* Clean up the region we want to draw to. */ - XftDrawRect(xw.draw, bg, winx, winy, width, win.ch); - - /* Set the clip region because Xft is sometimes dirty. */ - r.x = 0; - r.y = 0; - r.height = win.ch; - r.width = width; - XftDrawSetClipRectangles(xw.draw, winx, winy, &r, 1); - - /* Render the glyphs. */ - XftDrawGlyphFontSpec(xw.draw, fg, specs, len); - - /* Render underline and strikethrough. */ - if (base.mode & ATTR_UNDERLINE) { - XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1, - width, 1); - } - - if (base.mode & ATTR_STRUCK) { - XftDrawRect(xw.draw, fg, winx, winy + 2 * dc.font.ascent / 3, - width, 1); - } - - /* Reset clip to none. */ - XftDrawSetClip(xw.draw, 0); -} - -void -xdrawglyph(Glyph g, int x, int y) -{ - int numspecs; - XftGlyphFontSpec spec; - - numspecs = xmakeglyphfontspecs(&spec, &g, 1, x, y); - xdrawglyphfontspecs(&spec, g, numspecs, x, y); -} - -void -xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) -{ - Color drawcol; - - /* remove the old cursor */ - if (selected(ox, oy)) - og.mode ^= ATTR_REVERSE; - xdrawglyph(og, ox, oy); - - if (IS_SET(MODE_HIDE)) - return; - - /* - * Select the right color for the right mode. - */ - g.mode &= ATTR_BOLD|ATTR_ITALIC|ATTR_UNDERLINE|ATTR_STRUCK|ATTR_WIDE; - - if (IS_SET(MODE_REVERSE)) { - g.mode |= ATTR_REVERSE; - g.bg = defaultfg; - if (selected(cx, cy)) { - drawcol = dc.col[defaultcs]; - g.fg = defaultrcs; - } else { - drawcol = dc.col[defaultrcs]; - g.fg = defaultcs; - } - } else { - if (selected(cx, cy)) { - g.fg = defaultfg; - g.bg = defaultrcs; - } else { - g.fg = defaultbg; - g.bg = defaultcs; - } - drawcol = dc.col[g.bg]; - } - - /* draw the new one */ - if (IS_SET(MODE_FOCUSED)) { - switch (win.cursor) { - case 7: /* st extension */ - g.u = 0x2603; /* snowman (U+2603) */ - /* FALLTHROUGH */ - case 0: /* Blinking Block */ - case 1: /* Blinking Block (Default) */ - case 2: /* Steady Block */ - xdrawglyph(g, cx, cy); - break; - case 3: /* Blinking Underline */ - case 4: /* Steady Underline */ - XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + (cy + 1) * win.ch - \ - cursorthickness, - win.cw, cursorthickness); - break; - case 5: /* Blinking bar */ - case 6: /* Steady bar */ - XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + cy * win.ch, - cursorthickness, win.ch); - break; - } - } else { - XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + cy * win.ch, - win.cw - 1, 1); - XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + cy * win.ch, - 1, win.ch - 1); - XftDrawRect(xw.draw, &drawcol, - borderpx + (cx + 1) * win.cw - 1, - borderpx + cy * win.ch, - 1, win.ch - 1); - XftDrawRect(xw.draw, &drawcol, - borderpx + cx * win.cw, - borderpx + (cy + 1) * win.ch - 1, - win.cw, 1); - } -} - -void -xsetenv(void) -{ - char buf[sizeof(long) * 8 + 1]; - - snprintf(buf, sizeof(buf), "%lu", xw.win); - setenv("WINDOWID", buf, 1); -} - -void -xseticontitle(char *p) -{ - XTextProperty prop; - DEFAULT(p, opt_title); - - Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, - &prop); - XSetWMIconName(xw.dpy, xw.win, &prop); - XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmiconname); - XFree(prop.value); -} - -void -xsettitle(char *p) -{ - XTextProperty prop; - DEFAULT(p, opt_title); - - Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, - &prop); - XSetWMName(xw.dpy, xw.win, &prop); - XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname); - XFree(prop.value); -} - -int -xstartdraw(void) -{ - return IS_SET(MODE_VISIBLE); -} - -void -xdrawline(Line line, int x1, int y1, int x2) -{ - int i, x, ox, numspecs; - Glyph base, new; - XftGlyphFontSpec *specs = xw.specbuf; - - numspecs = xmakeglyphfontspecs(specs, &line[x1], x2 - x1, x1, y1); - i = ox = 0; - for (x = x1; x < x2 && i < numspecs; x++) { - new = line[x]; - if (new.mode == ATTR_WDUMMY) - continue; - if (selected(x, y1)) - new.mode ^= ATTR_REVERSE; - if (i > 0 && ATTRCMP(base, new)) { - xdrawglyphfontspecs(specs, base, i, ox, y1); - specs += i; - numspecs -= i; - i = 0; - } - if (i == 0) { - ox = x; - base = new; - } - i++; - } - if (i > 0) - xdrawglyphfontspecs(specs, base, i, ox, y1); -} - -void -xfinishdraw(void) -{ - XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, - win.h, 0, 0); - XSetForeground(xw.dpy, dc.gc, - dc.col[IS_SET(MODE_REVERSE)? - defaultfg : defaultbg].pixel); -} - -void -xximspot(int x, int y) -{ - if (xw.ime.xic == NULL) - return; - - xw.ime.spot.x = borderpx + x * win.cw; - xw.ime.spot.y = borderpx + (y + 1) * win.ch; - - XSetICValues(xw.ime.xic, XNPreeditAttributes, xw.ime.spotlist, NULL); -} - -void -expose(XEvent *ev) -{ - redraw(); -} - -void -visibility(XEvent *ev) -{ - XVisibilityEvent *e = &ev->xvisibility; - - MODBIT(win.mode, e->state != VisibilityFullyObscured, MODE_VISIBLE); -} - -void -unmap(XEvent *ev) -{ - win.mode &= ~MODE_VISIBLE; -} - -void -xsetpointermotion(int set) -{ - MODBIT(xw.attrs.event_mask, set, PointerMotionMask); - XChangeWindowAttributes(xw.dpy, xw.win, CWEventMask, &xw.attrs); -} - -void -xsetmode(int set, unsigned int flags) -{ - int mode = win.mode; - MODBIT(win.mode, set, flags); - if ((win.mode & MODE_REVERSE) != (mode & MODE_REVERSE)) - redraw(); -} - -int -xsetcursor(int cursor) -{ - if (!BETWEEN(cursor, 0, 7)) /* 7: st extension */ - return 1; - win.cursor = cursor; - return 0; -} - -void -xseturgency(int add) -{ - XWMHints *h = XGetWMHints(xw.dpy, xw.win); - - MODBIT(h->flags, add, XUrgencyHint); - XSetWMHints(xw.dpy, xw.win, h); - XFree(h); -} - -void -xbell(void) -{ - if (!(IS_SET(MODE_FOCUSED))) - xseturgency(1); - if (bellvolume) - XkbBell(xw.dpy, xw.win, bellvolume, (Atom)NULL); -} - -void -focus(XEvent *ev) -{ - XFocusChangeEvent *e = &ev->xfocus; - - if (e->mode == NotifyGrab) - return; - - if (ev->type == FocusIn) { - if (xw.ime.xic) - XSetICFocus(xw.ime.xic); - win.mode |= MODE_FOCUSED; - xseturgency(0); - if (IS_SET(MODE_FOCUS)) - ttywrite("\033[I", 3, 0); - } else { - if (xw.ime.xic) - XUnsetICFocus(xw.ime.xic); - win.mode &= ~MODE_FOCUSED; - if (IS_SET(MODE_FOCUS)) - ttywrite("\033[O", 3, 0); - } -} - -int -match(uint mask, uint state) -{ - return mask == XK_ANY_MOD || mask == (state & ~ignoremod); -} - -char* -kmap(KeySym k, uint state) -{ - Key *kp; - int i; - - /* Check for mapped keys out of X11 function keys. */ - for (i = 0; i < LEN(mappedkeys); i++) { - if (mappedkeys[i] == k) - break; - } - if (i == LEN(mappedkeys)) { - if ((k & 0xFFFF) < 0xFD00) - return NULL; - } - - for (kp = key; kp < key + LEN(key); kp++) { - if (kp->k != k) - continue; - - if (!match(kp->mask, state)) - continue; - - if (IS_SET(MODE_APPKEYPAD) ? kp->appkey < 0 : kp->appkey > 0) - continue; - if (IS_SET(MODE_NUMLOCK) && kp->appkey == 2) - continue; - - if (IS_SET(MODE_APPCURSOR) ? kp->appcursor < 0 : kp->appcursor > 0) - continue; - - return kp->s; - } - - return NULL; -} - -void -kpress(XEvent *ev) -{ - XKeyEvent *e = &ev->xkey; - KeySym ksym; - char buf[64], *customkey; - int len; - Rune c; - Status status; - Shortcut *bp; - - if (IS_SET(MODE_KBDLOCK)) - return; - - if (xw.ime.xic) - len = XmbLookupString(xw.ime.xic, e, buf, sizeof buf, &ksym, &status); - else - len = XLookupString(e, buf, sizeof buf, &ksym, NULL); - /* 1. shortcuts */ - for (bp = shortcuts; bp < shortcuts + LEN(shortcuts); bp++) { - if (ksym == bp->keysym && match(bp->mod, e->state)) { - bp->func(&(bp->arg)); - return; - } - } - - /* 2. custom keys from config.h */ - if ((customkey = kmap(ksym, e->state))) { - ttywrite(customkey, strlen(customkey), 1); - return; - } - - /* 3. composed string from input method */ - if (len == 0) - return; - if (len == 1 && e->state & Mod1Mask) { - if (IS_SET(MODE_8BIT)) { - if (*buf < 0177) { - c = *buf | 0x80; - len = utf8encode(c, buf); - } - } else { - buf[1] = buf[0]; - buf[0] = '\033'; - len = 2; - } - } - ttywrite(buf, len, 1); -} - -void -cmessage(XEvent *e) -{ - /* - * See xembed specs - * http://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html - */ - if (e->xclient.message_type == xw.xembed && e->xclient.format == 32) { - if (e->xclient.data.l[1] == XEMBED_FOCUS_IN) { - win.mode |= MODE_FOCUSED; - xseturgency(0); - } else if (e->xclient.data.l[1] == XEMBED_FOCUS_OUT) { - win.mode &= ~MODE_FOCUSED; - } - } else if (e->xclient.data.l[0] == xw.wmdeletewin) { - ttyhangup(); - exit(0); - } -} - -void -resize(XEvent *e) -{ - if (e->xconfigure.width == win.w && e->xconfigure.height == win.h) - return; - - cresize(e->xconfigure.width, e->xconfigure.height); -} - -void -run(void) -{ - XEvent ev; - int w = win.w, h = win.h; - fd_set rfd; - int xfd = XConnectionNumber(xw.dpy), ttyfd, xev, drawing; - struct timespec seltv, *tv, now, lastblink, trigger; - double timeout; - - /* Waiting for window mapping */ - do { - XNextEvent(xw.dpy, &ev); - /* - * This XFilterEvent call is required because of XOpenIM. It - * does filter out the key event and some client message for - * the input method too. - */ - if (XFilterEvent(&ev, None)) - continue; - if (ev.type == ConfigureNotify) { - w = ev.xconfigure.width; - h = ev.xconfigure.height; - } - } while (ev.type != MapNotify); - - ttyfd = ttynew(opt_line, shell, opt_io, opt_cmd); - cresize(w, h); - - for (timeout = -1, drawing = 0, lastblink = (struct timespec){0};;) { - FD_ZERO(&rfd); - FD_SET(ttyfd, &rfd); - FD_SET(xfd, &rfd); - - if (XPending(xw.dpy)) - timeout = 0; /* existing events might not set xfd */ - - seltv.tv_sec = timeout / 1E3; - seltv.tv_nsec = 1E6 * (timeout - 1E3 * seltv.tv_sec); - tv = timeout >= 0 ? &seltv : NULL; - - if (pselect(MAX(xfd, ttyfd)+1, &rfd, NULL, NULL, tv, NULL) < 0) { - if (errno == EINTR) - continue; - die("select failed: %s\n", strerror(errno)); - } - clock_gettime(CLOCK_MONOTONIC, &now); - - if (FD_ISSET(ttyfd, &rfd)) - ttyread(); - - xev = 0; - while (XPending(xw.dpy)) { - xev = 1; - XNextEvent(xw.dpy, &ev); - if (XFilterEvent(&ev, None)) - continue; - if (handler[ev.type]) - (handler[ev.type])(&ev); - } - - /* - * To reduce flicker and tearing, when new content or event - * triggers drawing, we first wait a bit to ensure we got - * everything, and if nothing new arrives - we draw. - * We start with trying to wait minlatency ms. If more content - * arrives sooner, we retry with shorter and shorter periods, - * and eventually draw even without idle after maxlatency ms. - * Typically this results in low latency while interacting, - * maximum latency intervals during `cat huge.txt`, and perfect - * sync with periodic updates from animations/key-repeats/etc. - */ - if (FD_ISSET(ttyfd, &rfd) || xev) { - if (!drawing) { - trigger = now; - drawing = 1; - } - timeout = (maxlatency - TIMEDIFF(now, trigger)) \ - / maxlatency * minlatency; - if (timeout > 0) - continue; /* we have time, try to find idle */ - } - - /* idle detected or maxlatency exhausted -> draw */ - timeout = -1; - if (blinktimeout && tattrset(ATTR_BLINK)) { - timeout = blinktimeout - TIMEDIFF(now, lastblink); - if (timeout <= 0) { - if (-timeout > blinktimeout) /* start visible */ - win.mode |= MODE_BLINK; - win.mode ^= MODE_BLINK; - tsetdirtattr(ATTR_BLINK); - lastblink = now; - timeout = blinktimeout; - } - } - - draw(); - XFlush(xw.dpy); - drawing = 0; - } -} - -void -usage(void) -{ - die("usage: %s [-aiv] [-c class] [-f font] [-g geometry]" - " [-n name] [-o file]\n" - " [-T title] [-t title] [-w windowid]" - " [[-e] command [args ...]]\n" - " %s [-aiv] [-c class] [-f font] [-g geometry]" - " [-n name] [-o file]\n" - " [-T title] [-t title] [-w windowid] -l line" - " [stty_args ...]\n", argv0, argv0); -} - -int -main(int argc, char *argv[]) -{ - xw.l = xw.t = 0; - xw.isfixed = False; - xsetcursor(cursorshape); - - ARGBEGIN { - case 'a': - allowaltscreen = 0; - break; - case 'c': - opt_class = EARGF(usage()); - break; - case 'e': - if (argc > 0) - --argc, ++argv; - goto run; - case 'f': - opt_font = EARGF(usage()); - break; - case 'g': - xw.gm = XParseGeometry(EARGF(usage()), - &xw.l, &xw.t, &cols, &rows); - break; - case 'i': - xw.isfixed = 1; - break; - case 'o': - opt_io = EARGF(usage()); - break; - case 'l': - opt_line = EARGF(usage()); - break; - case 'n': - opt_name = EARGF(usage()); - break; - case 't': - case 'T': - opt_title = EARGF(usage()); - break; - case 'w': - opt_embed = EARGF(usage()); - break; - case 'v': - die("%s " VERSION "\n", argv0); - break; - default: - usage(); - } ARGEND; - -run: - if (argc > 0) /* eat all remaining arguments */ - opt_cmd = argv; - - if (!opt_title) - opt_title = (opt_line || !opt_cmd) ? "st" : opt_cmd[0]; - - setlocale(LC_CTYPE, ""); - XSetLocaleModifiers(""); - cols = MAX(cols, 1); - rows = MAX(rows, 1); - tnew(cols, rows); - xinit(cols, rows); - xsetenv(); - selinit(); - run(); - - return 0; -} diff --git a/time.sh b/time.sh deleted file mode 100755 index 371827b..0000000 --- a/time.sh +++ /dev/null @@ -1,7 +0,0 @@ - - ~/.vim/autoload/plug.vim --create-dirs \ - https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim - - - sh -c 'curl -fLo "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/autoload/plug.vim --create-dirs \ - https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim' diff --git a/image-links.txt b/wallpapers.txt similarity index 100% rename from image-links.txt rename to wallpapers.txt