This repository has been archived on 2021-10-03. You can view files and clone it, but cannot push or open issues or pull requests.
swm/wm.c

90 lines
No EOL
2.8 KiB
C

// Taken from https://github.com/mackstann/tinywm
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/XKBlib.h>
#define MODMASK Mod1Mask
#define MAX(a, b) ((a) > (b) ? (a) : (b))
static Window root;
static Display* dpy;
static XWindowAttributes attr;
static XButtonEvent start;
void grab_input(Window* root) {
XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("1")), MODMASK, *root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("Q")), MODMASK, *root, True, GrabModeAsync, GrabModeAsync);
XGrabButton(dpy, 1, MODMASK, *root, True, ButtonPressMask|ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None);
XGrabButton(dpy, 3, MODMASK, *root, True, ButtonPressMask|ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None);
}
void handle_event_keypress(XEvent *e) {
if (e->xkey.subwindow != None) {
KeySym keysym = XkbKeycodeToKeysym(dpy, e->xkey.keycode, 0, 0);
if (keysym == XK_q) {
XKillClient(dpy, e->xkey.subwindow);
} else if (keysym == XK_1) {
XRaiseWindow(dpy, e->xkey.subwindow);
}
}
}
void handle_event_buttonpress(XEvent *e) {
if (e->xkey.subwindow != None) {
XGetWindowAttributes(dpy, e->xbutton.subwindow, &attr);
start = e->xbutton;
}
}
void handle_event_motionnotify(XEvent *e) {
if (start.subwindow != None) {
int xdiff = e->xbutton.x_root - start.x_root;
int ydiff = e->xbutton.y_root - start.y_root;
XMoveResizeWindow(dpy, start.subwindow,
attr.x + (start.button==1 ? xdiff : 0),
attr.y + (start.button==1 ? ydiff : 0),
MAX(1, attr.width + (start.button==3 ? xdiff : 0)),
MAX(1, attr.height + (start.button==3 ? ydiff : 0)));
}
}
void handle_event_buttonrelease(XEvent *e) {
start.subwindow = None;
}
void handle_event_mappingnotify(XEvent *e) {
XMappingEvent *ev = &e->xmapping;
if (ev->request == MappingKeyboard || ev->request == MappingModifier) {
XRefreshKeyboardMapping(ev);
grab_input(&root);
}
}
static void (*event_handlers[LASTEvent])(XEvent *e) = {
[KeyPress] = handle_event_keypress,
[ButtonPress] = handle_event_buttonpress,
[ButtonRelease] = handle_event_buttonrelease,
[MotionNotify] = handle_event_motionnotify,
// Below are events that are not 100% needed but without them some programs may break!
// TODO: MapRequest, ConfigureRequest
[MappingNotify] = handle_event_mappingnotify
};
int main() {
if(!(dpy = XOpenDisplay(0x0))) return 1;
XEvent ev;
root = DefaultRootWindow(dpy);
grab_input(&root);
start.subwindow = None;
for (;;) {
XNextEvent(dpy, &ev);
if (event_handlers[ev.type]) event_handlers[ev.type](&ev);
}
return 0;
}