ADDED readme.md Index: readme.md ================================================================== --- readme.md +++ readme.md @@ -0,0 +1,4 @@ +# util +various odds and ends + +* **safekill.c**: utility to help keep from accidentally killing important windows; compile with `cc -Ofast safekill.c -lX11 -lc -osafekill` ADDED safekill.c Index: safekill.c ================================================================== --- safekill.c +++ safekill.c @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include +#include +typedef enum { false, true } bool; +char* isvital(char* str) { + start: // tail calls for dipshits + if (*str != '{') { + if (*str == 0) return 0; + ++str; goto start; + } else { + if (str[1] == 'V' && str[2] == '}') + return str; + else { ++str; goto start; } + } +} +int main(const int argc, const char** argv) { + Display *display; + Window focus; + int revert; + + bool active; + enum { vitalize, devitalize, hardkill, softkill } op; + + if (argc > 3) goto usage; + if (argc == 1) + op = softkill, active = true; + else { + if (argc == 2) active = true; + else active = false; + + if (argv[1][0] == '-' && argv[1][2] == 0) { // opt is short switch + switch (argv[1][1]) { // opt char + + // make window mission-critical + case 'v': op = vitalize; break; + + // make window acceptable loss + case 'c': op = devitalize; break; + + // liquidate by any means necessary + case 'q': op = hardkill; break; + + // with all due respect sir what the fuck + default: goto usage; + } + } else goto usage; + } + + display = XOpenDisplay(NULL); + + if (active) { + XGetInputFocus(display, &focus, &revert); + } else { + unsigned long temp = strtoul(argv[2], NULL, 0); + if (errno == EINVAL || errno == ERANGE) goto usage; + if (temp == 0) goto usage; + focus = (Window)temp; + } + + if(op == hardkill) { + XDestroyWindow(display,focus); + XSync(display,false); + return 0; + } + + XClassHint xclh; + if (XGetClassHint(display,focus,&xclh)) { + char* v; + if(v = isvital(xclh.res_class)) { + + if (op == vitalize) return 0; // nothing need be done + else if (op == devitalize) { + strcpy(v, v+3); + XSetClassHint(display,focus,&xclh); + XSync(display,false); + } else if (op == softkill) { + printf("softkill forbidden\n"); + return 1; // ACCESS DENIED + } + } else { + if (op == vitalize) { + size_t sz=strlen(xclh.res_class); // TODO: remove double-walk + xclh.res_class=realloc(xclh.res_class, sz+4); + xclh.res_class[sz]='{'; + xclh.res_class[sz+1]='V'; + xclh.res_class[sz+2]='}'; + xclh.res_class[sz+3]=0; + XSetClassHint(display,focus,&xclh); + XSync(display,false); + } else if (op == devitalize) return 0; + else if (op == softkill) { + // ice that motherfucker + XDestroyWindow(display,focus); + XSync(display,false); + return 3; + } + } + } else { + printf("\x1b[1merror:\x1b[m bad window\n"); + goto usage; + } + + return 0; + +usage: + #define info "\x1b[34m-- " + #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 + 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; +}