void identify_active_destroyed(FocusKeepStatus* stat, XEvent* ev) { assert(is_destroy_notify(ev)); if (extract_window_id(ev) == get_active_window(stat)) { LOG("Active window: %#lx is destroyed!\n", get_active_window(stat)); stat->active_window = 0; } }
int should_discard_focus_in_event(FocusKeepStatus* stat, Display* dpy, XEvent *ev) { int ret_val = FALSE; if (is_focus_in(ev) == FALSE) { return FALSE; } // Event not on active window - It's either on a new window currently being // created or on a different firefox one. On the first case, it will // be allowed through, but blocked on the second case. if (!event_on_active_or_adj_window(dpy, ev, get_active_window(stat))) { LOG("Got Focus in event on window %#lx but active window is %#lx\n", extract_window_id(ev), get_active_window(stat)); if (stat->new_window != 0) { // If we are in the process of a new window creation, do not ignore // this focus in event - allow it both for the new window // and for a child window of it. However, if this is a focus in // event for a child window (not the new window itself), then // steal focus back from it afterwards. ret_val = FALSE; Window curr_win = extract_window_id(ev); if (curr_win == stat->new_window) { LOG("FocusIn event on new window - allowing.\n"); } else { //if (event_on_active_or_adj_window(dpy, ev, stat->new_window) == FALSE) { if (window_ids_difference(curr_win, stat->new_window) > 4) { LOG("ERROR - Event on window %#lx\n", extract_window_id(ev)); } else { LOG("FocusIn event on child of new window - steal focus!\n"); } stat->should_steal_focus = TRUE; } } else { // Second case: No new window creation process disallow focus in ret_val = TRUE; } } else { // Event actually on the active window or an inferior window // of it. if (stat->encountered_focus_in_event == FALSE) { // If a focus in event for this window was not yet encountered, // allow this focus in event and ignore in the future. stat->encountered_focus_in_event = TRUE; ret_val = FALSE; } else { ret_val = TRUE; } } return ret_val; }
gboolean update_window_key_event(gpointer data) { AConvert *aconv = (AConvert *)data; aconv->keyboard->win=get_active_window(aconv->keyboard->dpy); if((aconv->keyboard->win == None) || (aconv->keyboard->win == PointerRoot)) return TRUE; WInfo *info = AddWindow(aconv->keyboard->win,aconv); if(info) { switch (get_find_name_to_grab(aconv,info)) { case -1: grab_wind_event(aconv); get_key_win(aconv); break; case 0: grab_wind_event(aconv); get_key_win(aconv); break; case 1: get_key_win(aconv); break; case 2: return TRUE; default: break; } } //get_key_win(aconv); return TRUE; }
void handle_event(Display *display) { XEvent event; /* Get current event of X display */ int result = XNextEvent(display, &event); if (result == Success && event.type == PropertyNotify) { if (event.xproperty.atom == active_window_prop) { Window win = get_active_window(event.xproperty.display, event.xproperty.window); if (win != None && win != active_window) { if (active_window_name) XFree(active_window_name); if (active_window_class) XFree(active_window_class); get_window_class_name(display, win, &active_window_class, &active_window_name); active_window_pid = get_window_pid(display, win); fprintf(stdout, "%d - \"%s\", \"%s\" - %li ms\n", active_window_pid, active_window_class, active_window_name, event.xproperty.time - activation_time); active_window = win; activation_time = event.xproperty.time; } } } else { fprintf(stderr, "Couldn't fetch event, error code %d\n", result); } }
bool window::select_activate(grid::POS dir) { Display* disp = XOpenDisplay(NULL); if (disp == NULL) { ERROR("unable to get display"); return false; } std::vector<Window> wins; { size_t win_count = 0; static Atom clientlist_msg = XInternAtom(disp, "_NET_CLIENT_LIST", False); Window* all_wins = (Window*)x11_util::get_property(disp, DefaultRootWindow(disp), XA_WINDOW, clientlist_msg, &win_count); if (all_wins == NULL || win_count == 0) { ERROR("unable to get list of windows"); if (all_wins != NULL) { x11_util::free_property(all_wins); } XCloseDisplay(disp); return false; } // only select normal windows, ignore docks and menus for (size_t i = 0; i < win_count; ++i) { if (!is_dock_window(disp, all_wins[i]) && !is_menu_window(disp, all_wins[i])) { wins.push_back(all_wins[i]); } } x11_util::free_property(all_wins); } size_t active_window = 0; dim_list_t all_windows; { Window* active = get_active_window(disp); if (active == NULL) { XCloseDisplay(disp); return false; } for (size_t i = 0; i < wins.size(); ++i) { if (wins[i] == *active) { active_window = i; DEBUG("ACTIVE:"); } all_windows.push_back(Dimensions()); get_window_size(disp, wins[i], &all_windows.back(), NULL, NULL); } x11_util::free_property(active); } size_t next_window; neighbor::select(dir, all_windows, active_window, next_window); bool ok = activate_window(disp, wins[active_window], wins[next_window]); XCloseDisplay(disp); return ok; }
int should_discard_focus_out_event(FocusKeepStatus* stat, Display* dpy, XEvent *ev) { int ret_val = FALSE; if (is_focus_out(ev) == FALSE) { return FALSE; } const int detail = ev->xfocus.detail; if (stat->new_window != 0) { /* if (!(event_on_active_or_adj_window(dpy, ev, stat->new_window) || event_on_active_or_adj_window(dpy, ev, get_active_window(stat)))) { LOG( "ERROR - Event on window %#lx, which is neither new nor active.\n", extract_window_id(ev)); } else */ { LOG("Event on new/active (%#lx) during new window creation, allowing.", extract_window_id(ev)); LOG(" New: %#lx Active: %#lx\n", stat->new_window, stat->active_window); } return FALSE; } if (event_on_active_or_adj_window(dpy, ev, get_active_window(stat))) { // If moving ownership between sub-windows of the same Firefox window. if ((detail == NotifyAncestor) || (detail == NotifyInferior)) { // Allow this one. LOG("Focus will move to ancestor / inferior (%d). Allowing.\n", detail); stat->encountered_focus_in_event = FALSE; } else { // Disallow transfer of focus to outside windows. if (!stat->active_window_from_close) { ret_val = TRUE; } else { LOG("FocusOut event, but active window from close. Not discarding.\n"); } } } else { LOG("Got Focus out event on window %#lx but active window is %#lx\n", extract_window_id(ev), get_active_window(stat)); } return ret_val; }
void api_display(const char *const msg) { if (msg == NULL) { return; } self_window = get_active_window(); line_info_add(self_window, NULL, NULL, NULL, SYS_MSG, 0, 0, msg); }
gboolean get_key_win(gpointer data) { AConvert *aconv = (AConvert *)data; XEvent xev; WInfo *info; Window w; info = win_find(aconv->keyboard->win,aconv); if(info) { if(aconv->sxkb->cur_group!=info->cur_group) { XkbLockGroup(aconv->keyboard->dpy, XkbUseCoreKbd, info->cur_group); update_flag(aconv->sxkb->group2info[aconv->sxkb->cur_group],aconv); } w=get_active_window(aconv->keyboard->dpy); if(info->win!=w) free_keysym_to_list(aconv); } { if (XPending(aconv->keyboard->dpy)) { XNextEvent (aconv->keyboard->dpy, &xev); switch (xev.type) { case KeyPress: if (xev.xkey.send_event == TRUE) return False; get_key_pres(aconv,&xev); info = win_find(aconv->keyboard->win,aconv); if(info) auto_convert_text(aconv,info); break; case DestroyNotify: if((xev.xdestroywindow.event == aconv->keyboard->root)) break; /* XGetInputFocus (aconv->keyboard->dpy,&w, &(aconv->keyboard->cur_status)); DEBUG_MSG("DestroyNotify ID %#x == ID %#x ++ ID %#x == ID %#x == ID %#x \n",(unsigned int) aconv->keyboard->win,(unsigned int)info->win,(unsigned int)w,(unsigned int)xev.xdestroywindow.window,(unsigned int)xev.xdestroywindow.event);*/ info = win_find(xev.xdestroywindow.event,aconv); if (info) { //printf ("Dest window: ID %#x \n",(unsigned int)info->win); win_free(info,aconv); } break; } } } return TRUE; }
void identify_new_window_situation(FocusKeepStatus* stat, XEvent* ev) { Window new_win = extract_window_id(ev); assert(is_reparent_notify(ev)); if (get_active_window(stat) != 0) { stat->new_window = new_win; LOG("New window being created: %#lx\n", stat->new_window); } else { LOG("Reparent notify for window: %#lx, but no active.\n", new_win); } }
void set_active_window(FocusKeepStatus* stat, XEvent* ev) { stat->active_window = extract_window_id(ev); if (stat->during_close) { stat->active_window_from_close = TRUE; } else { stat->active_window_from_close = FALSE; } stat->encountered_focus_in_event = FALSE; stat->during_switch = FALSE; unlink("/tmp/switch_window_started"); LOG("Setting Active Window due to FocusIn: %#lx (from close: %d)\n", get_active_window(stat), stat->active_window_from_close); }
void steal_focus_back_if_needed(FocusKeepStatus* stat, Display* dpy) { if ((stat->should_steal_focus) && (get_active_window(stat) != 0)) { stat->should_steal_focus = FALSE; if ((!stat->during_close) || (stat->active_window_from_close)) { LOG("Stealing focus back to %#lx\n", get_active_window(stat)); stat->new_window = 0; XSetInputFocus(dpy, get_active_window(stat), RevertToParent, CurrentTime); // Allow a focus in event to flow again to the window considered // active. stat->encountered_focus_in_event = FALSE; } else { LOG("Not stealing focus back. During close: %d Active from close: %d.\n", stat->during_close, stat->active_window_from_close); // Set during_close to false here - This is the point where the state // transition is done - specifically, we consider the entire close // process to be completed. stat->during_close = FALSE; } } }
void xConvert_text (gpointer data) { int mod=0; size_t slen; AConvert *aconv = (AConvert *)data; if(aconv==NULL) return; aconv->keyboard->win=get_active_window(aconv->keyboard->dpy); WInfo *info = win_find(aconv->keyboard->win,aconv); if (!info) return; slen =aconv->keyboard->gstr->len;//g_list_length (info->ks); if(slen<=0) { free_keysym_to_list(aconv); return ; } if(info->cur_group==(aconv->sxkb->ngroups-1)) info->cur_group=0; else if (info->cur_group < (aconv->sxkb->ngroups-1)) info->cur_group++; else info->cur_group=0; mod=(8192*info->cur_group); XkbLockGroup(aconv->keyboard->dpy, XkbUseCoreKbd,info->cur_group); update_flag(aconv->sxkb->group2info[aconv->sxkb->cur_group],aconv); delete_char_in_win(info->win,aconv->keyboard->iterator); backspace_char_in_win(info->win,slen-aconv->keyboard->iterator); aconv->keyboard->iterator=0; { GList *p = g_list_first (aconv->keyboard->ks); while (p) { Skeysym *sks=(Skeysym *)p->data; send_key_to_win(info->win,XKeysymToKeycode(aconv->keyboard->dpy,sks->key),mod+sks->mod); p = g_list_next (p); } } }
bool ActiveWindow::init() { if (disp == NULL) { disp = XOpenDisplay(NULL); if (disp == NULL) { ERROR("unable to get display"); return false; } } if (win == NULL) { win = get_active_window(disp); if (win == NULL) { return false; } } return true; }
int main(int argc, char **argv) { if (argc > 1) (void)(argv[1]); char *display_name = NULL; Display *display = NULL; /* Connect to X server */ display = XOpenDisplay(display_name); if (display == NULL) { fprintf(stderr, "Couldn't connect to X server %s\n", display_name); exit(EXIT_FAILURE); } active_window_prop = XInternAtom(display, "_NET_ACTIVE_WINDOW", False); /* Get root windows for every screen */ int screen_count = XScreenCount(display); Window *root_wins = calloc(screen_count, sizeof(Window*)); for (int i = 0; i < screen_count; i++) { root_wins[i] = XRootWindow(display, i); active_window = get_active_window(display, root_wins[i]); activation_time = get_time(display, active_window); int result = XSelectInput(display, root_wins[i], PropertyChangeMask); if (result == 0) fprintf(stderr, "Failed to attach handler to window #%i\n", i); } free(root_wins); while (True) handle_event(display); /* Clear resources */ if (active_window_name) XFree(active_window_name); if (active_window_class) XFree(active_window_class); /* Disconnect from X server */ XCloseDisplay(display); exit(0); }
bool title_changed(xcb_generic_event_t *evt, xcb_window_t *win, xcb_window_t *last_win) { if (XCB_EVENT_RESPONSE_TYPE(evt) == XCB_PROPERTY_NOTIFY) { xcb_property_notify_event_t *pne = (xcb_property_notify_event_t *) evt; if (pne->atom == ewmh->_NET_ACTIVE_WINDOW) { watch(*last_win, false); if (get_active_window(win)) { watch(*win, true); *last_win = *win; } else { *win = *last_win = XCB_NONE; } return true; } else if (*win != XCB_NONE && pne->window == *win && (pne->atom == ewmh->_NET_WM_NAME || pne->atom == XCB_ATOM_WM_NAME)) { return true; } } return false; }
/* * 执行快捷键指令 */ void exec_cmd_via_keys(int *keys) { int *tmp_key = keys; Display *disp = NULL; setlocale(LC_ALL, ""); if ( !(disp = XOpenDisplay(NULL)) ) { sys_err("Cannot open display...\n"); return ; } sys_err("create display ok!\n"); //activate_win(); match_wid = get_active_window(); if ( match_wid == (Window)0 ) { sys_err("match wid failed...\n"); XCloseDisplay(disp); return; } /* 设置指定窗口为焦点 */ XSetInputFocus(disp, match_wid, RevertToParent, CurrentTime); XFlush(disp); while ( XPending(disp) ) {} sys_err("set keys pressed...\n"); for (; *tmp_key != 0; tmp_key++ ) { send_key_press( disp, match_wid, *tmp_key ); } //usleep(500); sys_err("set keys release...\n"); tmp_key = keys; for (; *tmp_key != 0; tmp_key++ ) { send_key_release( disp, match_wid, *tmp_key ); } XCloseDisplay(disp); match_wid = (Window)0; }
void identify_switch_situation(FocusKeepStatus* stat) { if (stat->start_switch_window || stat->start_close_window) { // In the middle of a window switch. Window old_active = get_active_window(stat); stat->active_window = 0; stat->during_switch = TRUE; if (stat->start_close_window) { stat->during_close = TRUE; } LOG("Window switching detected, active was: %#lx close: %d\n", old_active, stat->during_close); // Reset the the flags. stat->start_switch_window = FALSE; stat->start_close_window = FALSE; } }
void identify_switch_situation(FocusKeepStatus* stat) { char switch_data[MAX_BUFFER_SIZE]; FILE* switch_fp = fopen("/tmp/switch_window_started", "r"); if (switch_fp != NULL) { // In the middle of a window switch. Window old_active = get_active_window(stat); stat->active_window = 0; stat->during_switch = TRUE; memset(switch_data, '\0', MAX_BUFFER_SIZE); fread(switch_data, sizeof(char), MAX_BUFFER_SIZE, switch_fp); fclose(switch_fp); unlink("/tmp/switch_window_started"); if (strstr(switch_data, "close:") == switch_data) { stat->during_close = TRUE; } LOG("Window switching detected, active was: %#lx info: %s close: %d\n", old_active, switch_data, stat->during_close); } }
void api_send(const char *msg) { if (msg == NULL || self_window->chatwin->cqueue == NULL) { return; } char *name = api_get_nick(); char timefrmt[TIME_STR_SIZE]; if (name == NULL) { return; } self_window = get_active_window(); get_time_str(timefrmt, sizeof(timefrmt)); strncpy((char *) self_window->chatwin->line, msg, sizeof(self_window->chatwin->line)); add_line_to_hist(self_window->chatwin); int id = line_info_add(self_window, timefrmt, name, NULL, OUT_MSG, 0, 0, "%s", msg); cqueue_add(self_window->chatwin->cqueue, msg, strlen(msg), OUT_MSG, id); free(name); }
static void open_files (GApplication *application, gboolean new_window, gboolean new_document, gchar *geometry, gint line_position, gint column_position, const GtkSourceEncoding *encoding, GInputStream *stdin_stream, GSList *file_list, GApplicationCommandLine *command_line) { GeditWindow *window = NULL; GeditTab *tab; gboolean doc_created = FALSE; if (!new_window) { window = get_active_window (GTK_APPLICATION (application)); } if (window == NULL) { gedit_debug_message (DEBUG_APP, "Create main window"); window = gedit_app_create_window (GEDIT_APP (application), NULL); gedit_debug_message (DEBUG_APP, "Show window"); gtk_widget_show (GTK_WIDGET (window)); } if (geometry) { gtk_window_parse_geometry (GTK_WINDOW (window), geometry); } if (stdin_stream) { gedit_debug_message (DEBUG_APP, "Load stdin"); tab = gedit_window_create_tab_from_stream (window, stdin_stream, encoding, line_position, column_position, TRUE); doc_created = tab != NULL; if (doc_created && command_line) { set_command_line_wait (GEDIT_APP (application), tab); } g_input_stream_close (stdin_stream, NULL, NULL); } if (file_list != NULL) { GSList *loaded; gedit_debug_message (DEBUG_APP, "Load files"); loaded = _gedit_cmd_load_files_from_prompt (window, file_list, encoding, line_position, column_position); doc_created = doc_created || loaded != NULL; if (command_line) { g_slist_foreach (loaded, (GFunc)set_command_line_wait_doc, GEDIT_APP (application)); } g_slist_free (loaded); } if (!doc_created || new_document) { gedit_debug_message (DEBUG_APP, "Create tab"); tab = gedit_window_create_tab (window, TRUE); if (command_line) { set_command_line_wait (GEDIT_APP (application), tab); } } gtk_window_present (GTK_WINDOW (window)); }
void xConvert_text_case (gpointer data) { int mod=0; size_t slen; AConvert *aconv = (AConvert *)data; if ((aconv==NULL)) return; aconv->keyboard->win=get_active_window(aconv->keyboard->dpy); WInfo *info = win_find(aconv->keyboard->win,aconv); if (!info) return; slen =aconv->keyboard->gstr->len;//g_list_length (info->ks); if(slen<=0) { free_keysym_to_list(aconv); return ; } if(aconv->dbase->count_case > 2) aconv->dbase->count_case=0; if(aconv->dbase->count_case==0) { aconv->dbase->count_case++; mod=(8192*info->cur_group); delete_char_in_win(info->win,aconv->keyboard->iterator); backspace_char_in_win(info->win,slen-aconv->keyboard->iterator); aconv->keyboard->iterator=0; { GList *p = g_list_first (aconv->keyboard->ks); while (p) { Skeysym *sks=(Skeysym *)p->data; send_key_to_win(info->win,XKeysymToKeycode(aconv->keyboard->dpy,sks->key),mod+1); p = g_list_next (p); } } return ; } else if(aconv->dbase->count_case==1) { aconv->dbase->count_case++; mod=(8192*info->cur_group); delete_char_in_win(info->win,aconv->keyboard->iterator); backspace_char_in_win(info->win,slen-aconv->keyboard->iterator); aconv->keyboard->iterator=0; { int i=1; GList *p = g_list_first (aconv->keyboard->ks); while (p) { Skeysym *sks=(Skeysym *)p->data; send_key_to_win(info->win,XKeysymToKeycode(aconv->keyboard->dpy,sks->key),mod+i); p = g_list_next (p); i=0; } } } else if(aconv->dbase->count_case==2) { aconv->dbase->count_case++; mod=(8192*info->cur_group); delete_char_in_win(info->win,aconv->keyboard->iterator); backspace_char_in_win(info->win,slen-aconv->keyboard->iterator); aconv->keyboard->iterator=0; { GList *p = g_list_first (aconv->keyboard->ks); while (p) { Skeysym *sks=(Skeysym *)p->data; send_key_to_win(info->win,XKeysymToKeycode(aconv->keyboard->dpy,sks->key),mod); p = g_list_next (p); } } return ; } else aconv->dbase->count_case=0; }
int action_window_str (Display *disp, char mode) {/*{{{*/ Window activate = 0; Window *client_list; unsigned long client_list_size; unsigned int i; if (strcmp(SELECT_WINDOW_MAGIC, options.param_window) == 0) { activate = Select_Window(disp); if (activate) { return action_window(disp, activate, mode); } else { return EXIT_FAILURE; } } if (strcmp(ACTIVE_WINDOW_MAGIC, options.param_window) == 0) { activate = get_active_window(disp); if (activate) { return action_window(disp, activate, mode); } else { return EXIT_FAILURE; } } else { if ((client_list = get_client_list(disp, &client_list_size)) == NULL) { return EXIT_FAILURE; } for (i = 0; i < client_list_size / sizeof(Window); i++) { gchar *match_utf8; if (options.show_class) { match_utf8 = get_window_class(disp, client_list[i]); /* UTF8 */ } else { match_utf8 = get_window_title(disp, client_list[i]); /* UTF8 */ } if (match_utf8) { gchar *match; gchar *match_cf; gchar *match_utf8_cf = NULL; if (envir_utf8) { match = g_strdup(options.param_window); match_cf = g_utf8_casefold(options.param_window, -1); } else { if (! (match = g_locale_to_utf8(options.param_window, -1, NULL, NULL, NULL))) { match = g_strdup(options.param_window); } match_cf = g_utf8_casefold(match, -1); } if (!match || !match_cf) { continue; } match_utf8_cf = g_utf8_casefold(match_utf8, -1); if ((options.full_window_title_match && strcmp(match_utf8, match) == 0) || (!options.full_window_title_match && strstr(match_utf8_cf, match_cf))) { activate = client_list[i]; g_free(match); g_free(match_cf); g_free(match_utf8); g_free(match_utf8_cf); break; } g_free(match); g_free(match_cf); g_free(match_utf8); g_free(match_utf8_cf); } } g_free(client_list); if (activate) { return action_window(disp, activate, mode); } else { return EXIT_FAILURE; } } }/*}}}*/
int XNextEvent(Display *display, XEvent *outEvent) { // Code to pull the real function handle from X11 library. void *handle = NULL; //This will turn the function proto into a function pointer declaration int (*real_func)(Display *display, XEvent *outEvent) = NULL; handle = get_xlib_handle(); if (handle == NULL) { return -1; } // The real event from XNextEvent XEvent realEvent; // Find the real function. real_func = dlsym(handle, "XNextEvent"); // Invoke the real function. int rf_ret = real_func(display, &realEvent); OPEN_LOGGING_FILE; if (g_library_inited == FALSE) { LOG("Library initialized.\n"); g_library_inited = TRUE; init_cached_xquerytree(); init_focus_keep_struct(&g_focus_status); } // This display object will be used to inquire X server // about inferior and parent windows. Display* dpy = display; //assert(dpy != NULL); print_event_to_log(dpy, &realEvent); // Is the event on a window other than the active one? // If so, update gActiveWindow on two cases: // 1. It's the first window known to the module. // 2. It's the second window known to the module. The second // window is the actual browser window (the first one is just a // set-up one). // if ((get_active_window(&g_focus_status) == 0) && (is_focus_in(&realEvent))) { set_active_window(&g_focus_status, &realEvent); } else { identify_switch_situation(&g_focus_status); } if (is_reparent_notify(&realEvent)) { identify_new_window_situation(&g_focus_status, &realEvent); } if (is_destroy_notify(&realEvent)) { identify_active_destroyed(&g_focus_status, &realEvent); } if ((g_focus_status.during_switch == TRUE) || (get_active_window(&g_focus_status) == 0)) { LOG("During switch: %d Active win: %#lx during close: %d\n", g_focus_status.during_switch, get_active_window(&g_focus_status), g_focus_status.during_close); *outEvent = realEvent; } else if (should_discard_focus_out_event(&g_focus_status, dpy, &realEvent)) { // Fake an event! fake_keymap_notify_event(outEvent, &realEvent); LOG("Fake event for focus out.\n"); } else if (should_discard_focus_in_event(&g_focus_status, dpy, &realEvent)) { fake_keymap_notify_event(outEvent, &realEvent); LOG("Fake event for focus in.\n"); } else { *outEvent = realEvent; } steal_focus_back_if_needed(&g_focus_status, dpy); dlclose(handle); CLOSE_LOGGING_FILE; return rf_ret; }
int main(int argc, char *argv[]) { bool snoop = false; char *format = NULL; char opt; while ((opt = getopt(argc, argv, "hvsf:")) != -1) { switch (opt) { case 'h': printf("xtitle [-h|-v|-s|-f FORMAT] [WID ...]\n"); return EXIT_SUCCESS; break; case 'v': printf("%s\n", VERSION); return EXIT_SUCCESS; break; case 's': snoop = true; break; case 'f': format = optarg; break; } } int num = argc - optind; char **args = argv + optind; setup(); char title[MAXLEN] = {0}; if (num > 0) { char *end; for (int i = 0; i < num; i++) { errno = 0; long int wid = strtol(args[i], &end, 0); if (errno != 0 || *end != '\0') warn("Invalid window ID: '%s'.\n", args[i]); else output_title(wid, format, title, sizeof(title)); } } else { xcb_window_t win = XCB_NONE; if (get_active_window(&win)) output_title(win, format, title, sizeof(title)); if (snoop) { signal(SIGINT, hold); signal(SIGHUP, hold); signal(SIGTERM, hold); watch(root, true); watch(win, true); xcb_window_t last_win = XCB_NONE; fd_set descriptors; int fd = xcb_get_file_descriptor(dpy); running = true; xcb_flush(dpy); while (running) { FD_ZERO(&descriptors); FD_SET(fd, &descriptors); if (select(fd + 1, &descriptors, NULL, NULL, NULL) > 0) { xcb_generic_event_t *evt; while ((evt = xcb_poll_for_event(dpy)) != NULL) { if (title_changed(evt, &win, &last_win)) output_title(win, format, title, sizeof(title)); free(evt); } } if (xcb_connection_has_error(dpy)) { warn("The server closed the connection.\n"); running = false; } } } } xcb_ewmh_connection_wipe(ewmh); free(ewmh); xcb_disconnect(dpy); return EXIT_SUCCESS; }
void api_execute(const char *input, int mode) { self_window = get_active_window(); execute(cur_window, self_window, user_tox, input, mode); }