/** Update the WM hints of a client. * \param c The client. * \param cookie Cookie returned by property_get_wm_hints. */ void property_update_wm_hints(client_t *c, xcb_get_property_cookie_t cookie) { xcb_icccm_wm_hints_t wmh; if(!xcb_icccm_get_wm_hints_reply(globalconf.connection, cookie, &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_INPUT) c->nofocus = !wmh.input; if(wmh.flags & XCB_ICCCM_WM_HINT_WINDOW_GROUP) client_set_group_window(globalconf.L, -1, wmh.window_group); if(!c->have_ewmh_icon) { if(wmh.flags & XCB_ICCCM_WM_HINT_ICON_PIXMAP) { if(wmh.flags & XCB_ICCCM_WM_HINT_ICON_MASK) client_set_icon_from_pixmaps(c, wmh.icon_pixmap, wmh.icon_mask); else client_set_icon_from_pixmaps(c, wmh.icon_pixmap, XCB_NONE); } else client_set_icon(c, NULL); } lua_pop(globalconf.L, 1); }
/** 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::updateHints(xcb_connection_t* conn, xcb_get_property_cookie_t cookie) { if (xcb_icccm_get_wm_hints_reply(conn, cookie, &mWmHints, 0)) { if (mWmHints.flags & XCB_ICCCM_WM_HINT_INPUT) { mNoFocus = !mWmHints.input; } } else { memset(&mWmHints, '\0', sizeof(mWmHints)); } }
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); }
//! Process WM_HINTS reply and update fields void Client::process_wm_hints(xcb_get_property_cookie_t gpc) { if (xcb_icccm_get_wm_hints_reply(g_xcb.connection, gpc, &m_wm_hints, NULL)) { INFO << "ICCCM: " << m_wm_hints; } else { WARN << "ICCCM WM_HINTS could not be retrieved."; } }
/** Update the WM hints of a client. * \param c The client. * \param cookie Cookie returned by property_get_wm_hints. */ void property_update_wm_hints(client_t *c, xcb_get_property_cookie_t cookie) { xcb_icccm_wm_hints_t wmh; if(!xcb_icccm_get_wm_hints_reply(globalconf.connection, cookie, &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_INPUT) c->nofocus = !wmh.input; if(wmh.flags & XCB_ICCCM_WM_HINT_WINDOW_GROUP) client_set_group_window(globalconf.L, -1, wmh.window_group); lua_pop(globalconf.L, 1); }
void property_notify(xcb_generic_event_t *evt) { xcb_property_notify_event_t *e = (xcb_property_notify_event_t *) evt; /* PRINTF("property notify %X\n", e->window); */ if (e->atom != XCB_ATOM_WM_HINTS && e->atom != XCB_ATOM_WM_NORMAL_HINTS) return; coordinates_t loc; if (!locate_window(e->window, &loc)) return; if (e->atom == XCB_ATOM_WM_HINTS) { xcb_icccm_wm_hints_t hints; if (xcb_icccm_get_wm_hints_reply(dpy, xcb_icccm_get_wm_hints(dpy, e->window), &hints, NULL) == 1 && (hints.flags & XCB_ICCCM_WM_HINT_X_URGENCY)) set_urgency(loc.monitor, loc.desktop, loc.node, xcb_icccm_wm_hints_get_urgency(&hints)); } else if (e->atom == XCB_ATOM_WM_NORMAL_HINTS) { client_t *c = loc.node->client; xcb_size_hints_t size_hints; if (xcb_icccm_get_wm_normal_hints_reply(dpy, xcb_icccm_get_wm_normal_hints(dpy, e->window), &size_hints, NULL) == 1 && (size_hints.flags & (XCB_ICCCM_SIZE_HINT_P_MIN_SIZE | XCB_ICCCM_SIZE_HINT_P_MAX_SIZE))) { c->min_width = size_hints.min_width; c->max_width = size_hints.max_width; c->min_height = size_hints.min_height; c->max_height = size_hints.max_height; int w = c->floating_rectangle.width; int h = c->floating_rectangle.height; restrain_floating_size(c, &w, &h); c->floating_rectangle.width = w; c->floating_rectangle.height = h; arrange(loc.monitor, loc.desktop); } } }
// === 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); }
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; }