// === CurrentWorkspace() === unsigned int LXCB::CurrentWorkspace(){ if(DEBUG){ qDebug() << "XCB: CurrentWorkspace()"; } //qDebug() << "Get Current Workspace"; xcb_get_property_cookie_t cookie = xcb_ewmh_get_current_desktop_unchecked(&EWMH, 0); uint32_t wkspace = 0; xcb_ewmh_get_current_desktop_reply(&EWMH, cookie, &wkspace, NULL); //qDebug() << " - done:" << wkspace; return wkspace; }
/* * Initialize yabar */ void ya_init() { signal(SIGTERM, ya_sighandler); signal(SIGINT, ya_sighandler); signal(SIGKILL, ya_sighandler); signal(SIGHUP, ya_sighandler); ya.depth = 32; ya.c = xcb_connect(NULL, NULL); ya.scr = xcb_setup_roots_iterator(xcb_get_setup(ya.c)).data; ya.visualtype = ya_get_visualtype(); if (ya.visualtype == NULL) { // if depth=32 not found, fallback to depth=24 ya.depth = 24; ya.visualtype = ya_get_visualtype(); } ya.colormap = xcb_generate_id(ya.c); xcb_create_colormap(ya.c, XCB_COLORMAP_ALLOC_NONE, ya.colormap, ya.scr->root, ya.visualtype->visual_id); const xcb_query_extension_reply_t *ya_reply; ya_reply = xcb_get_extension_data(ya.c, &xcb_randr_id); if (ya_reply->present) { ya.gen_flag |= GEN_RANDR; ya_init_randr(); } #ifdef YA_INTERNAL_EWMH ya.ewmh = malloc(sizeof(xcb_ewmh_connection_t)); if (xcb_ewmh_init_atoms_replies(ya.ewmh, xcb_ewmh_init_atoms(ya.c, ya.ewmh), NULL)==0) { fprintf(stderr, "Cannot use EWMH\n"); //Should exit program or not? //To be decided. } ya.lstwin = XCB_NONE; uint32_t evm = XCB_EVENT_MASK_PROPERTY_CHANGE; xcb_change_window_attributes(ya.c, ya.curwin, XCB_CW_EVENT_MASK, &evm); xcb_change_window_attributes(ya.c, ya.scr->root, XCB_CW_EVENT_MASK, &evm); xcb_get_property_cookie_t prop_ck = xcb_ewmh_get_active_window(ya.ewmh, 0); xcb_ewmh_get_active_window_reply(ya.ewmh, prop_ck, &ya.curwin, NULL); xcb_get_property_cookie_t ws_ck = xcb_ewmh_get_current_desktop(ya.ewmh, 0); xcb_ewmh_get_current_desktop_reply(ya.ewmh, ws_ck, &ya.curws, NULL); //fprintf(stderr, "WINNN = %x DESK= %x\n", ya.curwin, ya.curws); #endif //YA_INTERNAL_EWMH ya_config_parse(); }
/* * Handle property notify events, called from ya_main when such events occur. */ void ya_handle_prop_notify(xcb_property_notify_event_t *ep) { uint32_t no_ev_val = XCB_EVENT_MASK_NO_EVENT; uint32_t pr_ev_val = XCB_EVENT_MASK_PROPERTY_CHANGE; ya_ewmh_blk *ewblk; if(ep->atom == ya.ewmh->_NET_ACTIVE_WINDOW) { xcb_get_property_cookie_t win_ck = xcb_ewmh_get_active_window(ya.ewmh, 0); xcb_ewmh_get_active_window_reply(ya.ewmh, win_ck, &ya.curwin, NULL); xcb_get_property_cookie_t ws_ck = xcb_ewmh_get_current_desktop(ya.ewmh, 0); xcb_ewmh_get_current_desktop_reply(ya.ewmh, ws_ck, &ya.curws, NULL); if (ya.curwin != ya.lstwin) { xcb_change_window_attributes(ya.c, ya.lstwin, XCB_CW_EVENT_MASK, &no_ev_val); xcb_change_window_attributes(ya.c, ya.curwin, XCB_CW_EVENT_MASK, &pr_ev_val); #ifdef YA_NOWIN_COL if(((ya.curwin == XCB_NONE) && (ya.lstwin != XCB_NONE)) || ((ya.curwin != XCB_NONE) && (ya.lstwin == XCB_NONE))) { ya_bar_t *bar = ya.curbar; for(;bar; bar= bar->next_bar) { if((bar->attr & BARA_DYN_COL)) ya_redraw_bar(bar); } } #endif //YA_NOWIN_COL } else if(ya.curwin==XCB_NONE && ya.lstwin==XCB_NONE) { //Don't return, used when switch between two empty workspaces } else { return; } } else if ((ep->atom == ya.ewmh->_NET_WM_NAME) || (ep->atom == ya.ewmh->_NET_WM_VISIBLE_NAME)) { //Same window, but title changed. Therefore don't return. } else { return; } for(ewblk = ya.ewmh_blk; ewblk; ewblk=ewblk->next_ewblk) { ya_exec_intern_ewmh_blk(ewblk->blk); } ya.lstwin = ya.curwin; ya.lstws = ya.curws; }
static int widget_update (struct widget *widget, xcb_ewmh_connection_t *ewmh, int screen_nbr) { unsigned short i; uint32_t desktop_curr, desktop_len, client_desktop; char desktop_name[COPY_PROP_BUFSIZ]; xcb_ewmh_get_utf8_strings_reply_t desktop_names; xcb_ewmh_get_windows_reply_t clients; xcb_icccm_wm_hints_t window_hints; struct desktop *desktops; /* get current desktop */ int desktop_curr_success = xcb_ewmh_get_current_desktop_reply(ewmh, xcb_ewmh_get_current_desktop_unchecked(ewmh, screen_nbr), &desktop_curr, NULL); if (!desktop_curr_success) { LOG_DEBUG("ewmh: could not get current desktop"); return 1; } /* get desktop count */ int desktop_len_success = xcb_ewmh_get_number_of_desktops_reply(ewmh, xcb_ewmh_get_number_of_desktops_unchecked(ewmh, screen_nbr), &desktop_len, NULL); if (!desktop_len_success) { LOG_DEBUG("ewmh: could not get desktop count"); return 2; } desktops = calloc(desktop_len, sizeof(struct desktop)); int desktop_names_success = xcb_ewmh_get_desktop_names_reply(ewmh, xcb_ewmh_get_desktop_names_unchecked(ewmh, screen_nbr), &desktop_names, NULL); if (!desktop_names_success) { LOG_DEBUG("ewmh: could not get desktop names"); } for (i = 0; i < desktop_len; i++) { desktops[i].is_selected = i == desktop_curr; desktops[i].is_urgent = false; desktops[i].clients_len = 0; if (desktop_names_success && desktop_names.strings) { copy_prop(desktop_name, desktop_names.strings, desktop_names.strings_len, i, desktop_len); } else { snprintf(desktop_name, COPY_PROP_BUFSIZ - 1, "%i", i + 1); } desktops[i].name = strndup(desktop_name, strlen(desktop_name)); } /* get clients */ int clients_success = xcb_ewmh_get_client_list_reply(ewmh, xcb_ewmh_get_client_list_unchecked(ewmh, screen_nbr), &clients, NULL); if (!clients_success) { LOG_DEBUG("ewmh: could not get client list"); } else { for (i = 0; i < clients.windows_len; i++) { if (!xcb_ewmh_get_wm_desktop_reply(ewmh, xcb_ewmh_get_wm_desktop_unchecked(ewmh, clients.windows[i]), &client_desktop, NULL)) { /* window isn't associated with a desktop */ continue; } desktops[client_desktop].clients_len++; /* check icccm urgency hint on client */ if (!xcb_icccm_get_wm_hints_reply(ewmh->connection, xcb_icccm_get_wm_hints_unchecked(ewmh->connection, clients.windows[i]), &window_hints, NULL)) { LOG_DEBUG("icccm: could not get window hints"); } if (window_hints.flags & XCB_ICCCM_WM_HINT_X_URGENCY) { desktops[client_desktop].is_urgent = true; } } } json_t *json_data_object = json_object(); json_t *json_desktops_array = json_array(); json_object_set_new(json_data_object, "desktops", json_desktops_array); for (i = 0; i < desktop_len; i++) { json_t *json_desktop = json_object(); json_object_set_new(json_desktop, "name", json_string(desktops[i].name)); json_object_set_new(json_desktop, "clients_len", json_integer(desktops[i].clients_len)); json_object_set_new(json_desktop, "is_urgent", json_boolean(desktops[i].is_urgent)); json_array_append_new(json_desktops_array, json_desktop); if (desktops[i].is_selected) { json_object_set_new(json_data_object, "current_desktop", json_integer(i)); } } char *json_str = strdup(json_dumps(json_data_object, 0)); widget_data_callback(widget, widget_data_arg_string(json_str)); json_decref(json_data_object); free(json_str); /* cleanup */ if (desktop_names_success) { xcb_ewmh_get_utf8_strings_reply_wipe(&desktop_names); } if (clients_success) { xcb_ewmh_get_windows_reply_wipe(&clients); } for (i = 0; i < desktop_len; i++) { free(desktops[i].name); } free(desktops); return 0; }
// determine which monitor holds the active window, or failing that the mouse pointer void monitor_active ( workarea *mon ) { xcb_window_t root = xcb->screen->root; int x, y; if ( config.monitor >= 0 ) { if ( monitor_get_dimension ( config.monitor, mon ) ) { return; } fprintf ( stderr, "Failed to find selected monitor.\n" ); } if ( config.monitor == -3 ) { if ( pointer_get ( root, &x, &y ) ) { monitor_dimensions ( x, y, mon ); mon->x = x; mon->y = y; return; } } // Get the current desktop. unsigned int current_desktop = 0; if ( config.monitor == -1 && xcb_ewmh_get_current_desktop_reply ( &xcb->ewmh, xcb_ewmh_get_current_desktop ( &xcb->ewmh, xcb->screen_nbr ), ¤t_desktop, NULL ) ) { xcb_get_property_cookie_t c = xcb_ewmh_get_desktop_viewport ( &xcb->ewmh, xcb->screen_nbr ); xcb_ewmh_get_desktop_viewport_reply_t vp; if ( xcb_ewmh_get_desktop_viewport_reply ( &xcb->ewmh, c, &vp, NULL ) ) { if ( current_desktop < vp.desktop_viewport_len ) { monitor_dimensions ( vp.desktop_viewport[current_desktop].x, vp.desktop_viewport[current_desktop].y, mon ); xcb_ewmh_get_desktop_viewport_reply_wipe ( &vp ); return; } xcb_ewmh_get_desktop_viewport_reply_wipe ( &vp ); } } xcb_window_t active_window; if ( xcb_ewmh_get_active_window_reply ( &xcb->ewmh, xcb_ewmh_get_active_window ( &xcb->ewmh, xcb->screen_nbr ), &active_window, NULL ) ) { // get geometry. xcb_get_geometry_cookie_t c = xcb_get_geometry ( xcb->connection, active_window ); xcb_get_geometry_reply_t *r = xcb_get_geometry_reply ( xcb->connection, c, NULL ); if ( r ) { xcb_translate_coordinates_cookie_t ct = xcb_translate_coordinates ( xcb->connection, active_window, root, r->x, r->y ); xcb_translate_coordinates_reply_t *t = xcb_translate_coordinates_reply ( xcb->connection, ct, NULL ); if ( t ) { if ( config.monitor == -2 ) { // place the menu above the window // if some window is focused, place menu above window, else fall // back to selected monitor. mon->x = t->dst_x - r->x; mon->y = t->dst_y - r->y; mon->w = r->width; mon->h = r->height; mon->t = r->border_width; mon->b = r->border_width; mon->l = r->border_width; mon->r = r->border_width; free ( r ); free ( t ); return; } else if ( config.monitor == -4 ){ monitor_dimensions ( t->dst_x, t->dst_y, mon ); free(r); free(t); return; } } free ( r ); } } if ( pointer_get ( root, &x, &y ) ) { monitor_dimensions ( x, y, mon ); return; } monitor_dimensions ( 0, 0, mon ); }