diff options
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | src/defs.h | 43 | ||||
-rw-r--r-- | src/sxwm.c | 102 | ||||
-rw-r--r-- | src/sxwm.h | 27 | ||||
-rw-r--r-- | src/user.config | 6 | ||||
-rw-r--r-- | src/usercfg.h | 16 | ||||
-rw-r--r-- | src/util.h | 4 | ||||
-rw-r--r-- | src/utils.c | 1 |
8 files changed, 157 insertions, 47 deletions
@@ -18,7 +18,4 @@ $(SRC_DIR)/%.o: $(SRC_DIR)/%.c c: rm -f $(SRC_DIR)/*.o $(BIN) -r: - x all - -.PHONY: all clean rebuild +.PHONY: all c diff --git a/src/defs.h b/src/defs.h new file mode 100644 index 0000000..a09ba13 --- /dev/null +++ b/src/defs.h @@ -0,0 +1,43 @@ +#ifndef DEFS_H +#define DEFS_H + +#include <X11/Xlib.h> + +#define SXWM_VERSION "sxwm ver. 0.1.0" +#define SXWM_AUTHOR "(C) Abhinav Prasai 2025" +#define SXWM_LICINFO "See LICENSE for more info" + +#define ALT Mod1Mask +#define SUPER Mod4Mask +#define SHIFT ShiftMask + +#define BIND(mod, key, cmdstr) { (mod), XK_##key, { cmdstr }, 0 } +#define CALL(mod, key, fnptr) { (mod), XK_##key, { .fn = fnptr }, 1 } + +#define MAXCLIENTS 64 + +typedef void +(*EventHandler)(XEvent *); + +typedef union { + const char **cmd; + void (*fn)(void); +} Action; + +typedef struct { + unsigned int mods; + KeySym keysym; + Action action; + int is_func; +} Binding; + +typedef struct { + Window id; + int x, y; + unsigned int w, h; + unsigned int bw; + Bool isfocused; + Bool isfloating; +} Client; + +#endif @@ -11,12 +11,65 @@ */// (C) Abhinav Prasai 2025 -#include "sxwm.h" +#include <err.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include <X11/Xlib.h> +#include <X11/XKBlib.h> + +#include "defs.h" + +typedef void (*EventHandler)(XEvent *); + +static void hdl_dummy(XEvent *xev); +static void hdl_keypress(XEvent *xev); +static void other_wm(void); +static int other_wm_err(Display *dpy, XErrorEvent *ee); +static void quit(void); +static void run(void); +static void setup(void); +static void spawn(const char **cmd); +static int xerr(Display *dpy, XErrorEvent *ee); +static void xev_case(XEvent *xev); + +static Client clients[MAXCLIENTS] = {0}; +static EventHandler evtable[LASTEvent]; +static Display *dpy; +static Window root; + +#include "usercfg.h" + +static void +hdl_dummy(XEvent *xev){} static void -otherwm(void) +hdl_keypress(XEvent *xev) { - XSetErrorHandler(otherwmerr); + KeySym keysym; + XKeyEvent *ev = &xev->xkey; + unsigned int modifiers; + + modifiers = ev->state; + keysym = XkbKeycodeToKeysym(dpy, ev->keycode, 0, 0); + + int lenbindings = sizeof(binds) / sizeof(binds[0]); + for (int i = 0; i < lenbindings; ++i) { + if (keysym == binds[i].keysym && modifiers == binds[i].mods) { + if (binds[i].is_func) + binds[i].action.fn(); + else + spawn(binds[i].action.cmd); + return; + } + } +} + +static void +other_wm(void) +{ + XSetErrorHandler(other_wm_err); XChangeWindowAttributes(dpy, root, CWEventMask, &(XSetWindowAttributes){.event_mask = SubstructureRedirectMask}); XSync(dpy, False); @@ -25,7 +78,7 @@ otherwm(void) } static int -otherwmerr(Display *dpy, XErrorEvent *ee) +other_wm_err(Display *dpy, XErrorEvent *ee) { errx(0, "sxwm: can't start because another window manager is already running"); return 0; @@ -33,11 +86,18 @@ otherwmerr(Display *dpy, XErrorEvent *ee) } static void +quit(void) +{ + errx(0, "sxwm: quitting..."); +} + +static void run(void) { XEvent xev; for (;;) { XNextEvent(dpy, &xev); + xev_case(&xev); } } @@ -49,10 +109,33 @@ setup(void) errx(0, "sxwm: can't open display."); root = XDefaultRootWindow(dpy); - otherwm(); + other_wm(); XSelectInput(dpy, root, SubstructureRedirectMask | KeyPressMask | KeyReleaseMask ); + + for (int i = 0; i < LASTEvent; ++i) + evtable[i] = hdl_dummy; + + evtable[KeyPress] = hdl_keypress; +} + +static void +spawn(const char **cmd) +{ + if (!cmd) return; + printf("sxwm: attempting to spawn: %s\n", cmd[0]); + + pid_t pid = fork(); + if (pid == 0) { + if (dpy) + close(ConnectionNumber(dpy)); + setsid(); + execvp(cmd[0], (char *const*)cmd); + errx(1, "sxwm: execvp '%s' failed\n", cmd[0]); + } else if (pid < 0) { + fprintf(stderr, "sxwm: failed to fork process\n"); + } } static int @@ -64,6 +147,15 @@ xerr(Display *dpy, XErrorEvent *ee) if (dpy && ee) return 0; } +static void +xev_case(XEvent *xev) +{ + if (xev->type >= 0 && xev->type < LASTEvent) + evtable[xev->type](xev); + else + printf("sxwm: invalid event type: %d\n", xev->type); +} + int main(int ac, char **av) { diff --git a/src/sxwm.h b/src/sxwm.h deleted file mode 100644 index f1ef7e5..0000000 --- a/src/sxwm.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef SXWM_H -#define SXWM_H - -#include <stdio.h> -#include <string.h> -#include <err.h> -#include <X11/Xlib.h> - -#include "user.config" - -#define SXWM_VERSION "sxwm ver. 0.1.0" -#define SXWM_AUTHOR "(C) Abhinav Prasai 2025" -#define SXWM_LICINFO "See LICENSE for more info" - -#define ALT Mod1Mask -#define SUPER Mod4Mask -#define SHIFT ShiftMask - -static void otherwm(void); -static int otherwmerr(Display *dpy, XErrorEvent *ee); -static void run(void); -static void setup(void); -static int xerr(Display *dpy, XErrorEvent *ee); - -static Display *dpy; -static Window root; -#endif diff --git a/src/user.config b/src/user.config deleted file mode 100644 index f946501..0000000 --- a/src/user.config +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef USER_CONFIG -#define USER_CONFIG - -#define MODCONF Mod1Mask - -#endif diff --git a/src/usercfg.h b/src/usercfg.h new file mode 100644 index 0000000..111ae03 --- /dev/null +++ b/src/usercfg.h @@ -0,0 +1,16 @@ +#ifndef USER_CONFIG +#define USER_CONFIG + +#include <X11/keysym.h> +#include "defs.h" + +#define MOD ALT + +static const char *termcmd[] = {"st", NULL}; + +static const Binding binds[] = { + BIND(MOD, Return, termcmd), + CALL(MOD|SHIFT, q, quit), +}; + +#endif diff --git a/src/util.h b/src/util.h deleted file mode 100644 index 70a5ce8..0000000 --- a/src/util.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef UTIL_H -#define UTIL_H - -#endif diff --git a/src/utils.c b/src/utils.c deleted file mode 100644 index 408a76a..0000000 --- a/src/utils.c +++ /dev/null @@ -1 +0,0 @@ -#include "util.h" |