Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Initial Commit |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
14c3d4a28123d75e4c36fc8fc0158dc3 |
User & Date: | jmcclure 2018-01-03 19:29:16 |
Context
2018-01-03
| ||
21:15 | Added info check-in: 00626f0bb2 user: jmcclure tags: trunk | |
19:29 | Initial Commit check-in: 14c3d4a281 user: jmcclure tags: trunk | |
19:21 | initial empty check-in check-in: 4a38f900c5 user: jmcclure tags: trunk | |
Changes
Added Makefile.
> > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | CC ?= gcc PREFIX ?= /usr all: $(CC) -o xi xi.c $(CFLAGS) $(LDFLAGS) $(CC) -o wmutil wmutil.c $(CFLAGS) $(LDFLAGS) -lX11 $(CC) -o tmuxwm tmuxwm.c $(CFLAGS) $(LDFLAGS) -lX11 strip xi wmutil tmuxwm install: install -Dm0755 xi $(DESTDIR)$(PREFIX)/bin/xi install -Dm0755 wmutil $(DESTDIR)$(PREFIX)/bin/wmutil install -Dm0755 tmuxwm $(DESTDIR)$(PREFIX)/bin/tmuxwm clean: rm -f xi wmutil tmuxwm |
Added tmuxwm.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | /* tmuxwm.c * -------- * Minimalist WM with tmux session * -------- * * Copyright (c) 2017 Jesse McClure <code@jessemcclure.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <stdlib.h> #include <stdio.h> #include <signal.h> #include <unistd.h> #include <X11/Xlib.h> #include <X11/keysym.h> #include <X11/Xutil.h> #include <X11/XKBlib.h> typedef struct Bind { KeySym sym; int mod; const char * const *args; } Bind; typedef const char * const Arg[]; Arg tmux_client = (Arg) { "urxvt", "-e", "tmux", "new-session", "-AD", "-s", "TmuxWM", NULL }; static void cycle(void); #include <X11/XF86keysym.h> static Bind bind[] = { { XK_Return, ShiftMask | Mod4Mask, tmux_client }, { XK_Return, Mod4Mask, (Arg) { "tmux", "new-window", NULL } }, { XK_Tab, Mod4Mask, (Arg) { "tmux", "next-window", NULL } }, { XK_space, Mod4Mask, (Arg) { "plumb", NULL } }, { XK_1, Mod4Mask, (Arg) { "tmux", "select-window", "-t", "1", NULL } }, { XK_2, Mod4Mask, (Arg) { "tmux", "select-window", "-t", "2", NULL } }, { XK_3, Mod4Mask, (Arg) { "tmux", "select-window", "-t", "3", NULL } }, { XK_4, Mod4Mask, (Arg) { "tmux", "select-window", "-t", "4", NULL } }, { XK_5, Mod4Mask, (Arg) { "tmux", "select-window", "-t", "5", NULL } }, /* Launchers / Misc */ { XK_w, Mod4Mask, (Arg) { "qutebrowser", NULL} }, { XK_F4, Mod1Mask, (Arg) { "wmutil", "kill", NULL} }, { XK_Up, Mod4Mask, (Arg) { "wmutil", "move", "Y", "-10", NULL} }, { XK_Down, Mod4Mask, (Arg) { "wmutil", "move", "Y", "+10", NULL} }, { XK_Left, Mod4Mask, (Arg) { "wmutil", "move", "X", "-10", NULL} }, { XK_Right, Mod4Mask, (Arg) { "wmutil", "move", "X", "+10", NULL} }, { XK_Up, ShiftMask | Mod4Mask, (Arg) { "wmutil", "move", "H", "-10", NULL} }, { XK_Down, ShiftMask | Mod4Mask, (Arg) { "wmutil", "move", "H", "+10", NULL} }, { XK_Left, ShiftMask | Mod4Mask, (Arg) { "wmutil", "move", "W", "-10", NULL} }, { XK_Right, ShiftMask | Mod4Mask, (Arg) { "wmutil", "move", "W", "+10", NULL} }, { XF86XK_AudioRaiseVolume, 0, (Arg) { "amixer", "set", "Master", "2+", NULL} }, { XF86XK_AudioLowerVolume, 0, (Arg) { "amixer", "set", "Master", "2-", NULL} }, { XF86XK_AudioMute, 0, (Arg) { "amixer", "set", "Master", "toggle", NULL} }, { XF86XK_ScreenSaver, 0, (Arg) { "slock", NULL} }, }; static void configurerequest(XEvent *); static void enternotify(XEvent *); static void keypress(XEvent *); static void maprequest(XEvent *); static void unmapnotify(XEvent *); static Display *dpy; static Window root; static int sw, sh; static void (*handler[LASTEvent])(XEvent *) = { [ConfigureRequest] = configurerequest, [EnterNotify] = enternotify, [KeyPress] = keypress, [MapRequest] = maprequest, }; static int xerror(Display *d, XErrorEvent *e) { char msg[256]; XGetErrorText(d, e->error_code, msg, sizeof(msg)); return fprintf(stderr,"[X11 %d:%d] %s\n", e->request_code, e->error_code, msg); } static int spawn(Arg args) { if (fork() != 0) return 1; close(ConnectionNumber(dpy)); setsid(); if (fork() != 0) exit(0); return execvp(args[0], (char * const *) args); } int main(int argc, const char **argv) { signal(SIGCHLD, SIG_IGN); if(!(dpy = XOpenDisplay(0x0))) return 1; XSetErrorHandler(xerror); root = DefaultRootWindow(dpy); XSetWindowBackground(dpy, root, 0x060812); XDefineCursor(dpy, root, XCreateFontCursor(dpy, 68)); sw = DisplayWidth(dpy, DefaultScreen(dpy)); sh = DisplayHeight(dpy, DefaultScreen(dpy)); int i; XGrabKey(dpy, XKeysymToKeycode(dpy, XK_Tab), Mod1Mask, root, True, GrabModeAsync, GrabModeAsync); for (i = 0; i < sizeof(bind)/sizeof(bind[0]); ++i) XGrabKey(dpy, XKeysymToKeycode(dpy, bind[i].sym), bind[i].mod, root, True, GrabModeAsync, GrabModeAsync); XSelectInput(dpy, root, SubstructureNotifyMask | SubstructureRedirectMask); XEvent ev; spawn(tmux_client); while (!XNextEvent(dpy,&ev)) if (handler[ev.type]) handler[ev.type](&ev); return 0; } void configurerequest(XEvent *ev) { XConfigureRequestEvent *e = &ev->xconfigurerequest; int bpx = (e->x == 0 && e->y == 0 && e->width == sw && e->height == sh ? 0 : 2); XWindowChanges wc = { e->x, e->y, e->width, e->height, bpx, e->detail, Above }; XConfigureWindow(dpy, e->window, e->value_mask | CWBorderWidth, &wc); } void enternotify(XEvent *ev) { XSetInputFocus(dpy, ev->xcrossing.window, RevertToPointerRoot, CurrentTime); XRaiseWindow(dpy, ev->xcrossing.window); } void keypress(XEvent *ev) { XKeyEvent *e = &ev->xkey; KeySym sym = XkbKeycodeToKeysym(dpy, e->keycode, 0, 0); int i; if (e->state == Mod1Mask && sym == XK_Tab) XCirculateSubwindowsUp(dpy, root); else for (i = 0; i < sizeof(bind)/sizeof(bind[0]); ++i) if (bind[i].sym == sym && bind[i].mod == e->state) spawn(bind[i].args); } void maprequest(XEvent *ev) { XMapRequestEvent *e = &ev->xmaprequest; XWindowAttributes wa; if (!XGetWindowAttributes(dpy, e->window, &wa) || wa.override_redirect) return; XWMHints *wmHint = XGetWMHints(dpy,e->window); if (!(wmHint && wmHint->flags & InputHint && !wmHint->input)) XSelectInput(dpy, e->window, EnterWindowMask); if (wmHint) XFree(wmHint); Window parent; if (XGetTransientForHint(dpy, e->window, &parent)) XMoveResizeWindow(dpy, e->window, wa.x, wa.y, wa.width, wa.height); else XMoveResizeWindow(dpy, e->window, 0, 0, sw, sh); XSetWindowBorder(dpy, e->window, 0x000000); XMapWindow(dpy, e->window); } |
Added wmutil.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | /* wmutil.c * -------- * Window Manager Utilities * -------- * * Copyright (c) 2017 Jesse McClure <code@jessemcclure.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <X11/Xlib.h> #include <X11/Xatom.h> #include <X11/keysym.h> static Display *dpy; static Window root; static int sw, sh; void send_message(Window win, const char *type, const char *msg) { XEvent ev; ev.type = ClientMessage; ev.xclient.window = win; ev.xclient.message_type = XInternAtom(dpy, type, False); ev.xclient.format = 32; ev.xclient.data.l[0] = XInternAtom(dpy, msg, False);; ev.xclient.data.l[1] = CurrentTime; XSendEvent(dpy, win, False, NoEventMask, &ev); } void kill(Window win) { send_message(win, "WM_PROTOCOLS", "WM_DELETE_WINDOW"); } void external(Window win) { // TODO } void move_resize(Window win, const char *arg, int delta) { XWindowAttributes wa; XGetWindowAttributes(dpy, win, &wa); switch (arg[0]) { case 'h': case 'H': wa.height += delta; break; case 'w': case 'W': wa.width += delta; break; case 'x': case 'X': wa.x += delta; break; case 'y': case 'Y': wa.y += delta; break; } XMoveResizeWindow(dpy, win, wa.x, wa.y, wa.width, wa.height); } int main(int argc, char *const argv[]) { if (!(dpy = XOpenDisplay(0x0)) || argc < 2) return 1; root = DefaultRootWindow(dpy); sw = DisplayWidth(dpy, DefaultScreen(dpy)); sh = DisplayHeight(dpy, DefaultScreen(dpy)); Window win; int ig; if ((win=atoi(argv[1])) && argc > 2) argv++; else XGetInputFocus(dpy, &win, &ig); switch (argv[1][0]) { case 'e': case 'x': external(win); break; case 'k': kill(win); break; case 'm': if (argc > 3) move_resize(win, argv[2], atoi(argv[3])); break; case 's': if (argc > 3) send_message(win, argv[2], argv[3]); break; } XCloseDisplay(dpy); return 0; } |
Added xi.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | /* xi.c * ---- * Minimalist Xinit replacement * USAGE: xi $XDG_VTNR /path/to/wm * ---- * * Copyright (c) 2017 Jesse McClure <code@jessemcclure.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <stdlib.h> #include <stdio.h> #include <signal.h> #include <unistd.h> #include <sys/wait.h> #include <linux/limits.h> static volatile int xrunning = 0; void handler(int sig) { if (sig == SIGUSR1) xrunning = 1; if (sig == SIGCHLD || sig == SIGTERM) xrunning = 0; } int server(const char *dpy, const char *tty) { const char *xorg = "/usr/lib/xorg-server/Xorg"; int pid; if ((pid=fork()) < 0) exit(1); else if (pid > 0) return pid; signal(SIGTTIN, SIG_IGN); signal(SIGTTOU, SIG_IGN); signal(SIGUSR1, SIG_IGN); execl(xorg, xorg, dpy, tty, "-keeptty", "-nolisten", "tcp", "-quiet", NULL); _exit(2); } int client(const char *dpy, const char *wm) { int pid; if ((pid=fork()) < 0) exit(3); else if (pid > 0) return pid; char xauth[PATH_MAX]; snprintf(xauth, PATH_MAX, "%s/%s", getenv("HOME"), ".Xauthority"); setenv("XAUTHORITY", xauth, 1); setenv("DISPLAY", dpy, 1); execlp(wm, wm, NULL); _exit(4); } int main(int argc, const char **argv) { if (argc != 3 || argv[1][0] < '1' || argv[1][0] > '9') { fprintf(stderr,"USAGE: %s vt wm\n", argv[0]); return 1; } char dpy[] = ":1"; char tty[] = "vt1"; dpy[1] = argv[1][0]; tty[2] = argv[1][0]; struct sigaction sa = { 0, 0, 0, 0, 0 }; sa.sa_handler = handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGUSR1, &sa, NULL); sigaction(SIGCHLD, &sa, NULL); sigaction(SIGTERM, &sa, NULL); int xpid = server(dpy, tty); while (!xrunning) pause(); int cpid = client(dpy, argv[2]); while (xrunning) pause(); kill(cpid, SIGTERM); waitpid(cpid, NULL, 0); kill(xpid, SIGTERM); waitpid(xpid, NULL, 0); return 0; } |