@@ -6,8 +6,9 @@ * important windows on i3wm or whatever. */ #include #include +#include #include #include #include #include @@ -22,10 +23,36 @@ return str; else { ++str; goto start; } } } + +Display *display; + +void killwin(Window w) { + XEvent ev; + long mask = SubstructureRedirectMask | SubstructureNotifyMask; + ev.xclient.type = ClientMessage; + ev.xclient.serial = 0; + ev.xclient.send_event = True; + ev.xclient.message_type = XInternAtom(display, "_NET_CLOSE_WINDOW", False); + ev.xclient.window = w; + ev.xclient.format = 32; + + if(!XSendEvent(display, DefaultRootWindow(display), False, mask, &ev)) { + char* fallback = getenv("k_safekill_fallback"); + bool nofb = (*fallback == '0' && fallback[1] == 0); + + fprintf(stderr,"\x1b[1mwarning:\x1b[m cannot send _NET_CLOSE_WINDOW event to root window; is your window manager okay?"); + + if (nofb) { + fprintf(stderr,"\n"); + } else { + fprintf(stderr," falling back to XDestroyWindow, but this may wreck your shit - lots of multi-win apps do *not* like it.\n"); + XDestroyWindow(display,w); + } + } +} int main(const int argc, const char** argv) { - Display *display; Window focus; int revert; bool active; @@ -67,9 +94,9 @@ focus = (Window)temp; } if(op == hardkill) { - XDestroyWindow(display,focus); + killwin(focus); XSync(display,false); return 0; } @@ -83,9 +110,9 @@ strcpy(v, v+3); XSetClassHint(display,focus,&xclh); XSync(display,false); } else if (op == softkill) { - printf("softkill forbidden\n"); + fprintf(stderr, "softkill forbidden\n"); return 1; // ACCESS DENIED } } else { if (op == vitalize) { @@ -99,15 +126,15 @@ XSync(display,false); } else if (op == devitalize) return 0; else if (op == softkill) { // ice that motherfucker - XDestroyWindow(display,focus); + killwin(focus); XSync(display,false); return 3; } } } else { - printf("\x1b[1merror:\x1b[m bad window\n"); + fprintf(stderr,"\x1b[1merror:\x1b[m bad window\n"); goto usage; } return 0; @@ -117,11 +144,11 @@ #define param "\x1b[32m" #define eol "\x1b[m\n" #define bold "\x1b[1m" #define nl " " - printf(bold "usage:\x1b[0m %s " " " info "kill active window if non-vital" eol + fprintf(stderr, bold "usage:\x1b[0m %s " " " info "kill active window if non-vital" eol nl "%1$s -v " param "[id] " info "make [id] or active window vital" eol nl "%1$s -c " param "[id] " info "clear vital flag on [id] or active window" eol nl "%1$s -q " param "[id] " info "'emergency' kill w/o reference to vital flag" eol, argv[0]); return 1; }