From b32bdc2ca6224a4e50b90c56d392883ce5d0d133 Mon Sep 17 00:00:00 2001 From: Quantum Date: Sun, 15 Dec 2019 00:22:35 -0500 Subject: [PATCH] Add initial version of the code --- .clang-format | 7 +++ .gitignore | 3 ++ Makefile | 9 ++++ i3bgwin.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 134 insertions(+) create mode 100644 .clang-format create mode 100644 Makefile create mode 100644 i3bgwin.c diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..703a1c1 --- /dev/null +++ b/.clang-format @@ -0,0 +1,7 @@ +BasedOnStyle: LLVM +--- +Language: Cpp +DerivePointerAlignment: false +PointerAlignment: Right +AlwaysBreakTemplateDeclarations: true +ColumnLimit: 100 diff --git a/.gitignore b/.gitignore index c6127b3..d72ba35 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,6 @@ modules.order Module.symvers Mkfile.old dkms.conf + +# Our executable +i3bgwin diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d6e3d1a --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +CC=gcc +CFLAGS=-std=c99 -Wall -Wextra +LDFLAGS=-s +LDLIBS=-lX11 -lXext + +all: i3bgwin + +i3bgwin: i3bgwin.o + $(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS) diff --git a/i3bgwin.c b/i3bgwin.c new file mode 100644 index 0000000..cec512f --- /dev/null +++ b/i3bgwin.c @@ -0,0 +1,115 @@ +#define _DEFAULT_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + Display *display = XOpenDisplay(NULL); + if (display == NULL) { + fprintf(stderr, "Cannot open display\n"); + exit(1); + } + + int ignored; + if (!XShapeQueryExtension(display, &ignored, &ignored)) { + fprintf(stderr, "No SHAPE extension\n"); + exit(1); + } + + int screen = DefaultScreen(display); + XVisualInfo vinfo; + XMatchVisualInfo(display, screen, 32, TrueColor, &vinfo); + + XSetWindowAttributes attrs = {}; + attrs.event_mask = + SubstructureRedirectMask | SubstructureNotifyMask | StructureNotifyMask | ExposureMask; + attrs.do_not_propagate_mask = 0; + attrs.colormap = XCreateColormap(display, RootWindow(display, screen), vinfo.visual, AllocNone); + attrs.border_pixel = 0; + attrs.background_pixel = 0; + attrs.override_redirect = True; + + Window window = XCreateWindow( + display, RootWindow(display, screen), 0, 0, DisplayWidth(display, screen), + DisplayHeight(display, screen), 0, vinfo.depth, InputOutput, vinfo.visual, + CWEventMask | CWColormap | CWBorderPixel | NoEventMask | CWBackPixel | CWOverrideRedirect, + &attrs); + + Atom wmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", False); + XSetWMProtocols(display, window, &wmDeleteMessage, 1); + + Atom netWmWindowType = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False); + Atom netWmWindowTypeDesktop = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DESKTOP", False); + XChangeProperty(display, window, netWmWindowType, XA_ATOM, 32, PropModeReplace, + (unsigned char *)&netWmWindowTypeDesktop, 1); + + XLowerWindow(display, window); + + Region region = XCreateRegion(); + XShapeCombineRegion(display, window, ShapeInput, 0, 0, region, ShapeSet); + XDestroyRegion(region); + + XMapWindow(display, window); + + pid_t pid = fork(); + if (pid == -1) { + perror("Failed to fork"); + exit(1); + } else if (pid == 0) { + char window_id[64]; + sprintf(window_id, "%lu", window); + + char **child_argv = calloc(argc, sizeof(char *)); + for (int i = 0; i < argc; ++i) { + if (argv[i + 1] && strcmp(argv[i + 1], "{windowid}") == 0) { + child_argv[i] = window_id; + } else { + child_argv[i] = argv[i + 1]; + } + } + + execvp(child_argv[0], child_argv); + + perror("Can't execute child process!"); + _exit(1); + } + + Display *child_display = NULL; + Window child_window = 0; + + while (1) { + XEvent event; + XNextEvent(display, &event); + + if (event.type == MapRequest) { + XMapWindow(event.xmaprequest.display, event.xmaprequest.window); + child_display = event.xmaprequest.display; + child_window = event.xmaprequest.window; + } else if (event.type == ConfigureNotify || event.type == MapRequest) { + if (child_window) { + XWindowAttributes attrs; + XGetWindowAttributes(display, window, &attrs); + XMoveResizeWindow(child_display, child_window, 0, 0, attrs.width, attrs.height); + } + } else if (event.type == Expose) { + XClearWindow(display, window); + } else if (event.type == DestroyNotify) { + break; + } else if (event.type == ClientMessage && event.xclient.data.l[0] == (long)wmDeleteMessage) { + break; + } + } + + kill(pid, SIGTERM); + wait(0); + + XCloseDisplay(display); + return 0; +}