summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoruint23 <[email protected]>2025-04-15 11:29:44 +0100
committeruint23 <[email protected]>2025-04-15 11:29:44 +0100
commitea8c0e5bdce00cc27d22c6c128d6e9a306ef2175 (patch)
tree3bfaa0f994cdd04cdadabc8da1f1eeb9de5a0843 /src
parent2341851145d9701e4b349a4ee80899d9e875b2bf (diff)
can quit
Diffstat (limited to 'src')
-rw-r--r--src/defs.h43
-rw-r--r--src/sxwm.c102
-rw-r--r--src/sxwm.h27
-rw-r--r--src/user.config6
-rw-r--r--src/usercfg.h16
-rw-r--r--src/util.h4
-rw-r--r--src/utils.c1
7 files changed, 156 insertions, 43 deletions
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
diff --git a/src/sxwm.c b/src/sxwm.c
index 5000f2e..c8d50ba 100644
--- a/src/sxwm.c
+++ b/src/sxwm.c
@@ -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"