diff
Makefile | 8 +++++--
wm.c | 74 +++++++++++++++++++++++++++++++---------------------------------
wmc.c | 49 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 91 insertions(+), 40 deletions(-)
diff --git a/Makefile b/Makefile
index 39a96ab..1260360 100644
--- a/Makefile
+++ b/Makefile
@@ -3,12 +3,16 @@ CPPFLAGS = -I/usr/X11R6/include
LDFLAGS = -L/usr/X11R6/lib
LDLIBS = -lX11
-all: wm
+all: wm wmc
wm: wm.c
cc $(CPPFLAGS) $(CFLAGS) -o wm wm.c $(LDFLAGS) $(LDLIBS)
+
+wmc: wmc.c
+ cc $(CPPFLAGS) $(CFLAGS) -o wmc wmc.c $(LDFLAGS) $(LDLIBS)
+
run: wm
./wm
clean:
- rm -f wm
+ rm -f wm wmc
diff --git a/wm.c b/wm.c
index d21cbfd..24156e2 100644
--- a/wm.c
+++ b/wm.c
@@ -1,9 +1,10 @@
#include <X11/Xlib.h>
-#include <X11/keysym.h>
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MODKEY Mod1Mask
#define MAXWINS 4096
+#define CMD_WS 1
+#define CMD_MOVE 2
static Window wins[MAXWINS];
static int ws[MAXWINS], nwin, curws;
@@ -23,19 +24,40 @@ getidx(Window w)
return nwin++;
}
+static void
+showws(Display *dpy, Window root)
+{
+ Window rootret, parent, *children;
+ int i, j, idx;
+
+ if (XQueryTree(dpy, root, &rootret, &parent, &children, (unsigned int *)&j)) {
+ for (i = 0; i < j; i++) {
+ idx = getidx(children[i]);
+ if (idx >= 0) {
+ if (ws[idx] == curws)
+ XMapWindow(dpy, children[i]);
+ else
+ XUnmapWindow(dpy, children[i]);
+ }
+ }
+ if (children != None)
+ XFree(children);
+ }
+}
+
int
main(void)
{
Display *dpy;
Window root;
Window dragwin;
- Window rootret, parent, *children, focus;
+ Window focus;
XWindowAttributes attr;
XButtonEvent start;
XEvent ev;
+ Atom ctl;
int dragging;
- int i, j, revert;
- KeySym ks;
+ int i, j;
dragging = 0;
dragwin = None;
@@ -43,15 +65,8 @@ main(void)
return 1;
root = DefaultRootWindow(dpy);
+ ctl = XInternAtom(dpy, "_WM_CTL", False);
- XGrabKey(dpy, XKeysymToKeycode(dpy, XK_F1), MODKEY, root,
- True, GrabModeAsync, GrabModeAsync);
- for (i = 0; i < 9; i++) {
- XGrabKey(dpy, XKeysymToKeycode(dpy, XK_1 + i), MODKEY, root,
- True, GrabModeAsync, GrabModeAsync);
- XGrabKey(dpy, XKeysymToKeycode(dpy, XK_1 + i), MODKEY | ShiftMask,
- root, True, GrabModeAsync, GrabModeAsync);
- }
XGrabButton(dpy, 1, MODKEY, root, True, ButtonPressMask, GrabModeAsync,
GrabModeAsync, None, None);
XGrabButton(dpy, 3, MODKEY, root, True, ButtonPressMask, GrabModeAsync,
@@ -59,39 +74,22 @@ main(void)
for (;;) {
XNextEvent(dpy, &ev);
- if (ev.type == KeyPress) {
- ks = XLookupKeysym(&ev.xkey, 0);
- if (ks >= XK_1 && ks <= XK_9) {
- i = (int)(ks - XK_1);
- if (ev.xkey.state & ShiftMask) {
- focus = ev.xkey.subwindow;
- if (focus == None)
- XGetInputFocus(dpy, &focus, &revert);
+ if (ev.type == ClientMessage && ev.xclient.message_type == ctl) {
+ i = (int)ev.xclient.data.l[1];
+ if (i >= 0 && i < 9) {
+ if (ev.xclient.data.l[0] == CMD_WS && i != curws) {
+ curws = i;
+ showws(dpy, root);
+ } else if (ev.xclient.data.l[0] == CMD_MOVE) {
+ XGetInputFocus(dpy, &focus, &j);
j = getidx(focus);
if (j >= 0) {
ws[j] = i;
if (i != curws)
XUnmapWindow(dpy, focus);
}
- } else if (i != curws) {
- curws = i;
- if (XQueryTree(dpy, root, &rootret, &parent, &children,
- (unsigned int *)&j)) {
- for (i = 0; i < j; i++) {
- revert = getidx(children[i]);
- if (revert >= 0) {
- if (ws[revert] == curws)
- XMapWindow(dpy, children[i]);
- else
- XUnmapWindow(dpy, children[i]);
- }
- }
- if (children != None)
- XFree(children);
- }
}
- } else if (ks == XK_F1 && ev.xkey.subwindow != None)
- XRaiseWindow(dpy, ev.xkey.subwindow);
+ }
} else if (ev.type == ButtonPress && ev.xbutton.subwindow != None) {
dragwin = ev.xbutton.subwindow;
j = getidx(dragwin);
diff --git a/wmc.c b/wmc.c
new file mode 100644
index 0000000..cd1d860
--- /dev/null
+++ b/wmc.c
@@ -0,0 +1,49 @@
+#include <X11/Xlib.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define CMD_WS 1
+#define CMD_MOVE 2
+
+int
+main(int argc, char **argv)
+{
+ Display *dpy;
+ Window root;
+ XEvent ev;
+ Atom ctl;
+ int cmd, ws;
+ char *end;
+
+ cmd = CMD_WS;
+ if (argc == 2)
+ ws = (int)strtol(argv[1], &end, 10);
+ else if (argc == 3 && !strcmp(argv[1], "move")) {
+ cmd = CMD_MOVE;
+ ws = (int)strtol(argv[2], &end, 10);
+ } else if (argc == 3 && !strcmp(argv[1], "ws"))
+ ws = (int)strtol(argv[2], &end, 10);
+ else {
+ fprintf(stderr, "usage: wmc [ws] 1-9 | wmc move 1-9\n");
+ return 1;
+ }
+ if (*end != '\0' || ws < 1 || ws > 9)
+ return 1;
+ if ((dpy = XOpenDisplay(NULL)) == NULL)
+ return 1;
+ root = DefaultRootWindow(dpy);
+ ctl = XInternAtom(dpy, "_WM_CTL", False);
+ memset(&ev, 0, sizeof(ev));
+ ev.xclient.type = ClientMessage;
+ ev.xclient.window = root;
+ ev.xclient.message_type = ctl;
+ ev.xclient.format = 32;
+ ev.xclient.data.l[0] = cmd;
+ ev.xclient.data.l[1] = ws - 1;
+ XSendEvent(dpy, root, False, SubstructureNotifyMask, &ev);
+ XFlush(dpy);
+ XCloseDisplay(dpy);
+ return 0;
+}