diff --git a/client.c b/client.c index b104d624..bfff0123 100644 --- a/client.c +++ b/client.c @@ -131,7 +131,11 @@ client_maybevisible(client_t *c, int screen) { if(c->screen == screen) { + if(c->issticky) + return true; + tag_array_t *tags = &globalconf.screens[screen].tags; + for(int i = 0; i < tags->len; i++) if(tags->tab[i]->selected && is_client_tagged(c, tags->tab[i])) return true; @@ -629,6 +633,21 @@ client_setfloating(client_t *c, bool floating) } } +/** Set a client sticky, or not. + * \param c The client. + * \param s Set or not the client sticky. + */ +void +client_setsticky(client_t *c, bool s) +{ + if(c->issticky != s) + { + client_need_arrange(c); + c->issticky = s; + client_need_arrange(c); + } +} + /** Save client properties as an X property. * \param c The client. */ @@ -1181,6 +1200,9 @@ luaA_client_newindex(lua_State *L) case A_TK_FLOATING: client_setfloating(*c, luaA_checkboolean(L, 3)); break; + case A_TK_STICKY: + client_setsticky(*c, luaA_checkboolean(L, 3)); + break; case A_TK_HONORSIZEHINTS: (*c)->honorsizehints = luaA_checkboolean(L, 3); client_need_arrange(*c); @@ -1352,6 +1374,9 @@ luaA_client_index(lua_State *L) case A_TK_FLOATING: lua_pushboolean(L, (*c)->isfloating); break; + case A_TK_STICKY: + lua_pushboolean(L, (*c)->issticky); + break; case A_TK_HONORSIZEHINTS: lua_pushboolean(L, (*c)->honorsizehints); break; diff --git a/client.h b/client.h index 14a33463..056f9d79 100644 --- a/client.h +++ b/client.h @@ -51,6 +51,7 @@ bool client_updatetitle(client_t *); void client_saveprops(client_t *); void client_kill(client_t *); void client_setfloating(client_t *, bool); +void client_setsticky(client_t *, bool); void client_setborder(client_t *, int); int luaA_client_newindex(lua_State *); diff --git a/common/tokenize.gperf b/common/tokenize.gperf index ce78c78a..06ae2146 100644 --- a/common/tokenize.gperf +++ b/common/tokenize.gperf @@ -52,6 +52,7 @@ selected shadow shadow_offset show_icons +sticky text ticks_count ticks_gap diff --git a/ewmh.c b/ewmh.c index a15f8940..f59c405e 100644 --- a/ewmh.c +++ b/ewmh.c @@ -252,9 +252,10 @@ ewmh_process_state_atom(client_t *c, xcb_atom_t state, int set) { if(state == _NET_WM_STATE_STICKY) { - tag_array_t *tags = &globalconf.screens[c->screen].tags; - for(int i = 0; i < tags->len; i++) - tag_client(c, tags->tab[i]); + if(set == _NET_WM_STATE_REMOVE) + client_setsticky(c, false); + else if(set == _NET_WM_STATE_ADD) + client_setsticky(c, true); } else if(state == _NET_WM_STATE_SKIP_TASKBAR) { @@ -432,8 +433,7 @@ ewmh_process_client_message(xcb_client_message_event_t *ev) tag_array_t *tags = &globalconf.screens[c->screen].tags; if(ev->data.data32[0] == 0xffffffff) - for(int i = 0; i < tags->len; i++) - tag_client(c, tags->tab[i]); + c->issticky = true; else for(int i = 0; i < tags->len; i++) if((int)ev->data.data32[0] == i) @@ -482,8 +482,7 @@ ewmh_check_client_hints(client_t *c) desktop = *(uint32_t *) data; if(desktop == -1) - for(int i = 0; i < tags->len; i++) - tag_client(c, tags->tab[i]); + c->issticky = true; else for(int i = 0; i < tags->len; i++) if(desktop == i) diff --git a/structs.h b/structs.h index f766fd63..6bbc7284 100644 --- a/structs.h +++ b/structs.h @@ -269,6 +269,8 @@ struct client_t xcolor_t border_color; /** True if the client does not want any border */ bool noborder; + /** True if the client is sticky */ + bool issticky; /** Has urgency hint */ bool isurgent; /** Store previous floating state before maximizing */