// spawn() heavily inspired by dwm.c int spawn(int argc, char** argv) { if (argc < 2) { return HERBST_NEED_MORE_ARGS; } if (fork() == 0) { // only look in child if (g_display) { close(ConnectionNumber(g_display)); } // shift all args in argv by 1 to the front // so that we have space for a NULL entry at the end for execvp char** execargs = argv_duplicate(argc, argv); free(execargs[0]); int i; for (i = 0; i < argc-1; i++) { execargs[i] = execargs[i+1]; } execargs[i] = NULL; // do actual exec setsid(); execvp(execargs[0], execargs); fprintf(stderr, "herbstluftwm: execvp \"%s\"", argv[1]); perror(" failed"); exit(0); } return 0; }
bool hc_next_hook(HCConnection* con, int* argc, char** argv[]) { if (!hc_hook_window_connect(con)) { return false; } // get window to listen at Window win = con->hook_window; // listen on window XEvent next_event; bool received_hook = false; while (!received_hook) { XNextEvent(con->display, &next_event); if (next_event.type == DestroyNotify) { if (next_event.xdestroywindow.window == win) { // hook window was destroyed // so quit idling return false; } } if (next_event.type != PropertyNotify) { fprintf(stderr, "Warning: got other event than PropertyNotify\n"); continue; } XPropertyEvent* pe = &next_event.xproperty; if (pe->state == PropertyDelete) { // just ignore property delete events continue; } if (pe->window != win) { fprintf(stderr, "Warning: expected event from window %u", (unsigned int)win); fprintf(stderr, " but got something from %u\n", (unsigned int)pe->window); continue; } XTextProperty text_prop; XGetTextProperty(con->display, win, &text_prop, pe->atom); char** list_return; int count; if (Success != Xutf8TextPropertyToTextList(con->display, &text_prop, &list_return, &count)) { XFree(text_prop.value); return false; } *argc = count; *argv = argv_duplicate(count, list_return); received_hook = true; // cleanup XFreeStringList(list_return); XFree(text_prop.value); } return true; }
int wmexec(int argc, char** argv) { if (argc >= 2) { // shift all args in argv by 1 to the front // so that we have space for a NULL entry at the end for execvp char** execargs = argv_duplicate(argc, argv); free(execargs[0]); int i; for (i = 0; i < argc-1; i++) { execargs[i] = execargs[i+1]; } execargs[i] = NULL; // quit and exec to new window manger g_exec_args = execargs; } else { // exec into same command g_exec_args = NULL; } g_exec_before_quit = true; g_aboutToQuit = true; return EXIT_SUCCESS; }
int mouse_bind_command(int argc, char** argv, GString* output) { if (argc < 3) { return HERBST_NEED_MORE_ARGS; } unsigned int modifiers = 0; char* string = argv[1]; if (!string2modifiers(string, &modifiers)) { g_string_append_printf(output, "%s: Modifier \"%s\" does not exist\n", argv[0], string); return HERBST_INVALID_ARGUMENT; } // last one is the mouse button const char* last_token = strlasttoken(string, KEY_COMBI_SEPARATORS); unsigned int button = string2button(last_token); if (button == 0) { g_string_append_printf(output, "%s: Unknown mouse button \"%s\"\n", argv[0], last_token); return HERBST_INVALID_ARGUMENT; } MouseFunction function = string2mousefunction(argv[2]); if (!function) { g_string_append_printf(output, "%s: Unknown mouse action \"%s\"\n", argv[0], argv[2]); return HERBST_INVALID_ARGUMENT; } // actually create a binding MouseBinding* mb = g_new(MouseBinding, 1); mb->button = button; mb->modifiers = modifiers; mb->action = function; mb->argc = argc - 3; mb->argv = argv_duplicate(argc - 3, argv + 3);; g_mouse_binds = g_list_prepend(g_mouse_binds, mb); HSClient* client = get_current_client(); if (client) { grab_client_buttons(client, true); } return 0; }