/** Update the WM hints of a client. * \param c The client. * \param reply (Optional) An existing reply. */ void property_update_wm_hints(client_t *c, xcb_get_property_reply_t *reply) { xcb_icccm_wm_hints_t wmh; if(reply) { if(!xcb_icccm_get_wm_hints_from_reply(&wmh, reply)) return; } else { if(!xcb_icccm_get_wm_hints_reply(globalconf.connection, xcb_icccm_get_wm_hints_unchecked(globalconf.connection, c->window), &wmh, NULL)) return; } luaA_object_push(globalconf.L, c); client_set_urgent(globalconf.L, -1, xcb_icccm_wm_hints_get_urgency(&wmh)); if(wmh.flags & XCB_ICCCM_WM_HINT_STATE && wmh.initial_state == XCB_ICCCM_WM_STATE_WITHDRAWN) client_set_border_width(globalconf.L, -1, 0); if(wmh.flags & XCB_ICCCM_WM_HINT_INPUT) c->nofocus = !wmh.input; if(wmh.flags & XCB_ICCCM_WM_HINT_WINDOW_GROUP) client_set_group_window(globalconf.L, -1, wmh.window_group); #ifdef LAB126 /* pop client */ lua_pop(globalconf.L, 1); #endif }
void client_clear_urgent(Client *c) { xcb_icccm_wm_hints_t wmh; xcb_get_property_cookie_t wmh_cookie; wmh_cookie = xcb_icccm_get_wm_hints_unchecked(conn, c->win); c->isurgent = false; if(!xcb_icccm_get_wm_hints_reply(conn, wmh_cookie, &wmh, NULL)) return; wmh.flags &= ~XCB_ICCCM_WM_HINT_X_URGENCY; xcb_icccm_set_wm_hints(conn, c->win, &wmh); }
// === SetAsPanel() === void LXCB::SetAsPanel(WId win){ if(DEBUG){ qDebug() << "XCB: SetAsPanel()"; } if(win==0){ return; } SetDisableWMActions(win); //also need to disable WM actions for this window //Disable Input focus (panel activation ruins task manager window detection routines) // - Disable Input flag in WM_HINTS xcb_icccm_wm_hints_t hints; //qDebug() << " - Disable WM_HINTS input flag"; xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_hints_unchecked(QX11Info::connection(), win); //qDebug() << " -- got cookie"; if(1 == xcb_icccm_get_wm_hints_reply(QX11Info::connection(), cookie, &hints, NULL) ){ //qDebug() << " -- Set no inputs flag"; xcb_icccm_wm_hints_set_input(&hints, false); //set no input focus xcb_icccm_set_wm_hints(QX11Info::connection(), win, &hints); //save hints back to window } // - Remove WM_TAKE_FOCUS from the WM_PROTOCOLS for the window // - - Generate the necessary atoms //qDebug() << " - Generate WM_PROTOCOLS and WM_TAKE_FOCUS atoms"; xcb_atom_t WM_PROTOCOLS, WM_TAKE_FOCUS; //the two atoms needed xcb_intern_atom_reply_t *preply = xcb_intern_atom_reply(QX11Info::connection(), \ xcb_intern_atom(QX11Info::connection(), 0, 12, "WM_PROTOCOLS"), NULL); xcb_intern_atom_reply_t *freply = xcb_intern_atom_reply(QX11Info::connection(), \ xcb_intern_atom(QX11Info::connection(), 0, 13, "WM_TAKE_FOCUS"), NULL); bool gotatoms = false; if(preply && freply){ WM_PROTOCOLS = preply->atom; WM_TAKE_FOCUS = freply->atom; free(preply); free(freply); gotatoms = true; //qDebug() << " -- success"; } // - - Now update the protocols for the window if(gotatoms){ //requires the atoms //qDebug() << " - Get WM_PROTOCOLS"; xcb_icccm_get_wm_protocols_reply_t proto; if( 1 == xcb_icccm_get_wm_protocols_reply(QX11Info::connection(), \ xcb_icccm_get_wm_protocols_unchecked(QX11Info::connection(), win, WM_PROTOCOLS), \ &proto, NULL) ){ //Found the current protocols, see if it has the focus atom set //remove the take focus atom and re-save them bool needremove = false; //Note: This first loop is required so that we can initialize the modified list with a valid size //qDebug() << " -- Check current protocols"; for(unsigned int i=0; i<proto.atoms_len; i++){ if(proto.atoms[i] == WM_TAKE_FOCUS){ needremove = true; break;} } if(needremove){ //qDebug() << " -- Remove WM_TAKE_FOCUS protocol"; xcb_atom_t *protolist = new xcb_atom_t[proto.atoms_len-1]; int num = 0; for(unsigned int i=0; i<proto.atoms_len; i++){ if(proto.atoms[i] != WM_TAKE_FOCUS){ protolist[num] = proto.atoms[i]; num++; } } //qDebug() << " -- Re-save modified protocols"; xcb_icccm_set_wm_protocols(QX11Info::connection(), win, WM_PROTOCOLS, num, protolist); } //qDebug() << " -- Clear protocols reply"; xcb_icccm_get_wm_protocols_reply_wipe(&proto); }//end of get protocols check } //end of gotatoms check //Make sure it has the "dock" window type // - get the current window types (Not necessary, only 1 type of window needed) // - set the adjusted window type(s) //qDebug() << " - Adjust window type"; xcb_atom_t list[1]; list[0] = EWMH._NET_WM_WINDOW_TYPE_DOCK; xcb_ewmh_set_wm_window_type(&EWMH, win, 1, list); //Make sure it is on all workspaces //qDebug() << " - Set window as sticky"; SetAsSticky(win); }
xcb_get_property_cookie_t property_get_wm_hints(client_t *c) { return xcb_icccm_get_wm_hints_unchecked(globalconf.connection, c->window); }
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; }