#include #include #include #include #include #include struct win { Window w_win; Window w_titlebar; TAILQ_ENTRY(win) w_list; }; Display *display; Window win, rootwindow; int screen, width, height, numwins; TAILQ_HEAD(winhead, win); struct winhead winhead; void create_titlebar(struct win *w) { XSetWindowAttributes attr; attr.override_redirect = 1; attr.background_pixmap = ParentRelative; attr.event_mask = SubstructureRedirectMask | SubstructureNotifyMask; w->w_titlebar = XCreateWindow(display, rootwindow, 0, 0, 10, 10, 2, CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect | CWBackPixmap | CWEventMask, &attr); XMapWindow(display, w->w_titlebar); } void reorganize(void) { XWindowChanges changes; struct win *w; int i; i = 0; TAILQ_FOREACH(w, &winhead, w_list) { changes.x = width / numwins * i; changes.y = 10; changes.width = width / numwins; changes.height = height - 10; XConfigureWindow(display, w->w_win, CWX | CWY | CWWidth | CWHeight, &changes); changes.y = 0; changes.height = 10; XConfigureWindow(display, w->w_titlebar, CWX | CWY | CWWidth | CWHeight, &changes); i++; } } int main(void) { XEvent ev; display = XOpenDisplay(":1"); if (!display) errx(1, "XOpenDisplay"); screen = DefaultScreen(display); width = XDisplayWidth(display, screen); height = XDisplayHeight(display, screen); rootwindow = RootWindow(display, screen); printf("Display with %dx%d\n", width, height); if (XSelectInput(display, rootwindow, EnterWindowMask | LeaveWindowMask | SubstructureNotifyMask | StructureNotifyMask) == BadWindow) errx(1, "XSelectInput"); numwins = 0; while (1) { struct win *win, *w, *tmp; int found; XNextEvent(display, &ev); switch (ev.type) { case MapNotify: found = 0; TAILQ_FOREACH(w, &winhead, w_list) if (w->w_titlebar == ev.xconfigure.window) { found = 1; break; } if (found) break; numwins++; win = malloc(sizeof(*win)); win->w_win = ev.xconfigure.window; create_titlebar(win); TAILQ_INSERT_HEAD(&winhead, win, w_list); reorganize(); break; case UnmapNotify: found = 0; TAILQ_FOREACH(w, &winhead, w_list) if (w->w_titlebar == ev.xconfigure.window) { found = 1; break; } if (found) break; numwins--; TAILQ_FOREACH_SAFE(w, &winhead, w_list, tmp) { if (w->w_win == ev.xconfigure.window) { TAILQ_REMOVE(&winhead, w, w_list); XDestroyWindow(display, w->w_titlebar); free(w); break; } } reorganize(); break; default: printf("got event %d!\n", ev.type); } } return (0); }