diff --git a/client.c b/client.c index a0ad2e2e..3510df7a 100644 --- a/client.c +++ b/client.c @@ -368,6 +368,7 @@ client_manage(Window w, XWindowAttributes *wa, int screen) focus(c, True, screen); + ewmh_check_client_hints(c); ewmh_update_net_client_list(c->phys_screen); /* rearrange to display new window */ diff --git a/ewmh.c b/ewmh.c index cee7a878..b300122e 100644 --- a/ewmh.c +++ b/ewmh.c @@ -40,6 +40,8 @@ static Atom net_close_window; static Atom net_wm_name; static Atom net_wm_icon; +static Atom net_wm_state; +static Atom net_wm_state_sticky; static Atom utf8_string; @@ -62,6 +64,8 @@ static AtomItem AtomNames[] = { "_NET_WM_NAME", &net_wm_name }, { "_NET_WM_ICON", &net_wm_icon }, + { "_NET_WM_STATE", &net_wm_state }, + { "_NET_WM_STATE_STICKY", &net_wm_state_sticky }, { "UTF8_STRING", &utf8_string }, }; @@ -99,6 +103,8 @@ ewmh_set_supported_hints(int phys_screen) atom[i++] = net_wm_name; atom[i++] = net_wm_icon; + atom[i++] = net_wm_state; + atom[i++] = net_wm_state_sticky; XChangeProperty(globalconf.display, RootWindow(globalconf.display, phys_screen), net_supported, XA_ATOM, 32, @@ -190,14 +196,56 @@ ewmh_update_net_active_window(int phys_screen) net_active_window, XA_WINDOW, 32, PropModeReplace, (unsigned char *) &win, 1); } +static void +ewmh_process_state_atom(Client *c, Atom state) +{ + if(state == net_wm_state_sticky) + { + Tag *tag; + for(tag = globalconf.screens[c->screen].tags; tag; tag = tag->next) + tag_client(c, tag, c->screen); + } +} + void ewmh_process_client_message(XClientMessageEvent *ev) { Client *c; if(ev->message_type == net_close_window) + { if((c = get_client_bywin(globalconf.clients, ev->window))) client_kill(c); + } + else if(ev->message_type == net_wm_state) + { + if((c = get_client_bywin(globalconf.clients, ev->window))) + { + ewmh_process_state_atom(c, (Atom) ev->data.l[1]); + if(ev->data.l[2]) + ewmh_process_state_atom(c, (Atom) ev->data.l[2]); + } + } +} + +void +ewmh_check_client_hints(Client *c) +{ + int format; + Atom real, *state; + unsigned char *data = NULL; + unsigned long i, n, extra; + + if(XGetWindowProperty(globalconf.display, c->win, net_wm_state, 0L, LONG_MAX, False, + XA_ATOM, &real, &format, &n, &extra, + (unsigned char **) &data) != Success || !data) + return; + + state = (Atom *) data; + for(i = 0; i < n; i++) + ewmh_process_state_atom(c, state[i]); + + XFree(data); } // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/ewmh.h b/ewmh.h index d46a5fa1..75c4dfdc 100644 --- a/ewmh.h +++ b/ewmh.h @@ -22,7 +22,7 @@ #ifndef AWESOME_EWMH_H #define AWESOME_EWMH_H -#include +#include "config.h" void ewmh_init_atoms(void); void ewmh_set_supported_hints(int); @@ -32,6 +32,7 @@ void ewmh_update_net_current_desktop(int); void ewmh_update_net_desktop_names(int); void ewmh_update_net_active_window(int); void ewmh_process_client_message(XClientMessageEvent *); +void ewmh_check_client_hints(Client *); #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80