mirror of
https://github.com/quantum5/i3bgwin.git
synced 2025-04-24 05:31:57 -04:00
Add initial version of the code
This commit is contained in:
parent
e1ccd13398
commit
b32bdc2ca6
7
.clang-format
Normal file
7
.clang-format
Normal file
|
@ -0,0 +1,7 @@
|
|||
BasedOnStyle: LLVM
|
||||
---
|
||||
Language: Cpp
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Right
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
ColumnLimit: 100
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -50,3 +50,6 @@ modules.order
|
|||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
# Our executable
|
||||
i3bgwin
|
||||
|
|
9
Makefile
Normal file
9
Makefile
Normal file
|
@ -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)
|
115
i3bgwin.c
Normal file
115
i3bgwin.c
Normal file
|
@ -0,0 +1,115 @@
|
|||
#define _DEFAULT_SOURCE
|
||||
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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;
|
||||
}
|
Loading…
Reference in a new issue