void handle_state(monitor_t *m, desktop_t *d, node_t *n, xcb_atom_t state, unsigned int action) { if (state == ewmh->_NET_WM_STATE_FULLSCREEN) { if (action == XCB_EWMH_WM_STATE_ADD) { set_state(m, d, n, STATE_FULLSCREEN); } else if (action == XCB_EWMH_WM_STATE_REMOVE) { if (n->client->state == STATE_FULLSCREEN) { set_state(m, d, n, n->client->last_state); } } else if (action == XCB_EWMH_WM_STATE_TOGGLE) { set_state(m, d, n, IS_FULLSCREEN(n->client) ? n->client->last_state : STATE_FULLSCREEN); } arrange(m, d); } else if (state == ewmh->_NET_WM_STATE_BELOW) { if (action == XCB_EWMH_WM_STATE_ADD) { set_layer(m, d, n, LAYER_BELOW); } else if (action == XCB_EWMH_WM_STATE_REMOVE) { if (n->client->layer == LAYER_BELOW) { set_layer(m, d, n, n->client->last_layer); } } else if (action == XCB_EWMH_WM_STATE_TOGGLE) { set_layer(m, d, n, n->client->layer == LAYER_BELOW ? n->client->last_layer : LAYER_BELOW); } } else if (state == ewmh->_NET_WM_STATE_ABOVE) { if (action == XCB_EWMH_WM_STATE_ADD) { set_layer(m, d, n, LAYER_ABOVE); } else if (action == XCB_EWMH_WM_STATE_REMOVE) { if (n->client->layer == LAYER_ABOVE) { set_layer(m, d, n, n->client->last_layer); } } else if (action == XCB_EWMH_WM_STATE_TOGGLE) { set_layer(m, d, n, n->client->layer == LAYER_ABOVE ? n->client->last_layer : LAYER_ABOVE); } } else if (state == ewmh->_NET_WM_STATE_STICKY) { if (action == XCB_EWMH_WM_STATE_ADD) { set_sticky(m, d, n, true); } else if (action == XCB_EWMH_WM_STATE_REMOVE) { set_sticky(m, d, n, false); } else if (action == XCB_EWMH_WM_STATE_TOGGLE) { set_sticky(m, d, n, !n->sticky); } } else if (state == ewmh->_NET_WM_STATE_DEMANDS_ATTENTION) { if (action == XCB_EWMH_WM_STATE_ADD) { set_urgent(m, d, n, true); } else if (action == XCB_EWMH_WM_STATE_REMOVE) { set_urgent(m, d, n, false); } else if (action == XCB_EWMH_WM_STATE_TOGGLE) { set_urgent(m, d, n, !n->client->urgent); } } }
char * message_client(Client *c, IxpMsg *m) { char *s; int i; s = getword(m); switch(getsym(s)) { case LKILL: kill_client(c); break; case LURGENT: i = gettoggle(m); if(i == -1) return Ebadusage; set_urgent(c, i, True); break; case LFULLSCREEN: i = gettoggle(m); if(i == -1) return Ebadusage; fullscreen(c, i); break; default: return Ebadcmd; } return nil; }
/** * @brief Handle client messages that are related to WM_STATE. * * TODO: Add more WM_STATE hints. * * @param c The client that is to have its WM_STATE modified. * @param a The atom representing which WM_STATE hint should be modified. * @param action Whether to remove, add or toggle the WM_STATE hint. */ void ewmh_process_wm_state(Client *c, xcb_atom_t a, int action) { if (a == ewmh->_NET_WM_STATE_FULLSCREEN) { if (action == _NET_WM_STATE_REMOVE) set_fullscreen(c, false); else if (action == _NET_WM_STATE_ADD) set_fullscreen(c, true); else if (action == _NET_WM_STATE_TOGGLE) set_fullscreen(c, !c->is_fullscreen); } else if (a == ewmh->_NET_WM_STATE_DEMANDS_ATTENTION) { if (action == _NET_WM_STATE_REMOVE) set_urgent(c, false); else if (action == _NET_WM_STATE_ADD) set_urgent(c, true); else if (action == _NET_WM_STATE_TOGGLE) set_urgent(c, !c->is_urgent); } else { log_warn("Unhandled wm state <%d> with action <%d>.", a, action); } }
void property_notify(xcb_generic_event_t *evt) { xcb_property_notify_event_t *e = (xcb_property_notify_event_t *) evt; 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_urgent(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); } } }