/** Check whether the given atom is actually supported by the window * manager thanks to _NET_SUPPORTED atom keeps up-to-date by the * window manager itself * * \param atom The Atom to look for * \return true if the Atom is supported */ bool atoms_is_supported(const xcb_atom_t atom) { /* Get the _NET_SUPPORTED reply if a request has been sent but not already processed */ if(globalconf.atoms_supported.cookie.sequence != 0) { /* Free existing value if needed */ if(globalconf.atoms_supported.initialised) { globalconf.atoms_supported.initialised = false; xcb_ewmh_get_atoms_reply_wipe(&globalconf.atoms_supported.value); } if(!xcb_ewmh_get_supported_reply(&globalconf.ewmh, globalconf.atoms_supported.cookie, &globalconf.atoms_supported.value, NULL)) return false; globalconf.atoms_supported.initialised = true; } else if(!globalconf.atoms_supported.initialised) return false; for(uint32_t atom_n = 0; atom_n < globalconf.atoms_supported.value.atoms_len; atom_n++) if(globalconf.atoms_supported.value.atoms[atom_n] == atom) return true; return false; }
void handle_rules(xcb_window_t win, bool *floating, bool *transient, bool *fullscreen, bool *takes_focus) { xcb_ewmh_get_atoms_reply_t win_type; if (xcb_ewmh_get_wm_window_type_reply(ewmh, xcb_ewmh_get_wm_window_type(ewmh, win), &win_type, NULL) == 1) { for (unsigned int i = 0; i < win_type.atoms_len; i++) { xcb_atom_t a = win_type.atoms[i]; if (a == ewmh->_NET_WM_WINDOW_TYPE_TOOLBAR || a == ewmh->_NET_WM_WINDOW_TYPE_UTILITY) { *takes_focus = false; } else if (a == ewmh->_NET_WM_WINDOW_TYPE_DIALOG) { *floating = true; } } xcb_ewmh_get_atoms_reply_wipe(&win_type); } xcb_ewmh_get_atoms_reply_t win_state; if (xcb_ewmh_get_wm_state_reply(ewmh, xcb_ewmh_get_wm_state(ewmh, win), &win_state, NULL) == 1) { for (unsigned int i = 0; i < win_state.atoms_len; i++) { xcb_atom_t a = win_state.atoms[i]; if (a == ewmh->_NET_WM_STATE_FULLSCREEN) { *fullscreen = true; } } xcb_ewmh_get_atoms_reply_wipe(&win_state); } xcb_window_t transient_for = XCB_NONE; xcb_icccm_get_wm_transient_for_reply(dpy, xcb_icccm_get_wm_transient_for(dpy, win), &transient_for, NULL); *transient = (transient_for == XCB_NONE ? false : true); if (*transient) *floating = true; rule_t *rule = rule_head; while (rule != NULL) { if (is_match(rule, win)) { if (rule->effect.floating) *floating = true; } rule = rule->next; } }
void Client::updateEwmhState(xcb_ewmh_connection_t* conn, xcb_get_property_cookie_t cookie) { warning() << "updating ewmh state"; mEwmhState.clear(); xcb_ewmh_get_atoms_reply_t prop; if (xcb_ewmh_get_wm_state_reply(conn, cookie, &prop, 0)) { for (uint32_t i = 0; i < prop.atoms_len; ++i) { warning() << "ewmh state has" << Atoms::name(prop.atoms[i]); mEwmhState.insert(prop.atoms[i]); } xcb_ewmh_get_atoms_reply_wipe(&prop); } }
/** On receiving a X PropertyNotify for _NET_SUPPORTED, its value * should be updated accordingly * * \param event The X PropertyNotify event received */ void atoms_update_supported(const xcb_property_notify_event_t *event) { if(globalconf.atoms_supported.initialised) { xcb_ewmh_get_atoms_reply_wipe(&globalconf.atoms_supported.value); globalconf.atoms_supported.initialised = false; globalconf.atoms_supported.cookie.sequence = 0; } if(event->state == XCB_PROPERTY_NEW_VALUE) globalconf.atoms_supported.cookie = xcb_ewmh_get_supported_unchecked(&globalconf.ewmh, globalconf.screen_nbr); }
bool ewmh_wm_type_dialog(const xcb_window_t win) { const xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_window_type_unchecked(cfg.ewmh, win); xcb_ewmh_get_atoms_reply_t data; if (!xcb_ewmh_get_wm_window_type_reply(cfg.ewmh, cookie, &data, (void *)0)) return false; bool state = false; for (unsigned short i = 0; i < data.atoms_len; i++) if ((state = data.atoms[i] == cfg.ewmh->_NET_WM_WINDOW_TYPE_DIALOG)) break; xcb_ewmh_get_atoms_reply_wipe(&data); return state; }
bool ewmh_wm_state_fullscreen(const xcb_window_t win) { const xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_state_unchecked(cfg.ewmh, win); xcb_ewmh_get_atoms_reply_t data; if (!xcb_ewmh_get_wm_state_reply(cfg.ewmh, cookie, &data, (void *)0)) return false; bool state = false; for (unsigned short i = 0; i < data.atoms_len; i++) if ((state = data.atoms[i] == cfg.ewmh->_NET_WM_STATE_FULLSCREEN)) break; xcb_ewmh_get_atoms_reply_wipe(&data); return state; }
void Client::updateWindowTypes(xcb_ewmh_connection_t* conn, xcb_get_property_cookie_t cookie) { mWindowTypes.clear(); xcb_ewmh_get_atoms_reply_t prop; if (xcb_ewmh_get_wm_window_type_reply(conn, cookie, &prop, 0)) { for (uint32_t i = 0; i < prop.atoms_len; ++i) { warning() << "window type has" << Atoms::name(prop.atoms[i]); mWindowTypes.append(prop.atoms[i]); } xcb_ewmh_get_atoms_reply_wipe(&prop); } if (mWindowTypes.contains(conn->_NET_WM_WINDOW_TYPE_DIALOG) && mTransientFor == XCB_NONE) { if (mGroup->leader() != mWindow) { mTransientFor = mGroup->leader(); } } }