diff --git a/client.c b/client.c index 00d15699f..13788ea5d 100644 --- a/client.c +++ b/client.c @@ -223,7 +223,7 @@ client_focus(client_t *c) /* stop hiding c */ c->ishidden = false; - c->isminimized = false; + client_setminimized(c, false); /* unban the client before focusing or it will fail */ client_unban(c); @@ -413,7 +413,7 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int phys_screen, screen_client_moveto(c, screen, false, true); /* Then check clients hints */ - ewmh_check_client_hints(c); + ewmh_client_check_hints(c); /* Check if client has been tagged by loading props, or maybe with its * hints. @@ -622,6 +622,22 @@ client_setfloating(client_t *c, bool floating) } } +/** Set a client minimized, or not. + * \param c The client. + * \param s Set or not the client minimized. + */ +void +client_setminimized(client_t *c, bool s) +{ + if(c->isminimized != s) + { + client_need_arrange(c); + c->isminimized = s; + client_need_arrange(c); + ewmh_client_update_hints(c); + } +} + /** Set a client sticky, or not. * \param c The client. * \param s Set or not the client sticky. @@ -634,6 +650,7 @@ client_setsticky(client_t *c, bool s) client_need_arrange(c); c->issticky = s; client_need_arrange(c); + ewmh_client_update_hints(c); } } @@ -678,6 +695,7 @@ client_setfullscreen(client_t *c, bool s) XCB_PROP_MODE_REPLACE, c->win, _AWESOME_FULLSCREEN, CARDINAL, 8, 1, &c->isfullscreen); + ewmh_client_update_hints(c); } } @@ -692,6 +710,7 @@ client_setabove(client_t *c, bool s) { c->isabove = s; client_stack(); + ewmh_client_update_hints(c); } } @@ -706,6 +725,7 @@ client_setbelow(client_t *c, bool s) { c->isbelow = s; client_stack(); + ewmh_client_update_hints(c); } } @@ -720,6 +740,7 @@ client_setmodal(client_t *c, bool s) { c->ismodal = s; client_stack(); + ewmh_client_update_hints(c); } } @@ -1184,13 +1205,7 @@ luaA_client_newindex(lua_State *L) } break; case A_TK_MINIMIZE: - b = luaA_checkboolean(L, 3); - if(b != (*c)->isminimized) - { - client_need_arrange(*c); - (*c)->isminimized = b; - client_need_arrange(*c); - } + client_setminimized(*c, luaA_checkboolean(L, 3)); break; case A_TK_FULLSCREEN: client_setfullscreen(*c, luaA_checkboolean(L, 3)); diff --git a/client.h b/client.h index 6139e42c5..9e7a8d5cc 100644 --- a/client.h +++ b/client.h @@ -52,6 +52,7 @@ void client_setbelow(client_t *, bool); void client_setmodal(client_t *, bool); void client_setontop(client_t *, bool); void client_setfullscreen(client_t *, bool); +void client_setminimized(client_t *, bool); void client_setborder(client_t *, int); int luaA_client_newindex(lua_State *); diff --git a/event.c b/event.c index e36951580..2733c0504 100644 --- a/event.c +++ b/event.c @@ -582,9 +582,7 @@ event_handle_maprequest(void *data __attribute__ ((unused)), /* Check that it may be visible, but not asked to be hidden */ if(client_maybevisible(c, c->screen) && !c->ishidden) { - c->isminimized = false; - globalconf.screens[c->screen].need_arrange = true; - xcb_map_window(globalconf.connection, ev->window); + client_setminimized(c, false); /* it will be raised, so just update ourself */ client_raise(c); } @@ -708,10 +706,7 @@ event_handle_clientmessage(void *data __attribute__ ((unused)), if((c = client_getbywin(ev->window)) && ev->format == 32 && ev->data.data32[0] == XCB_WM_STATE_ICONIC) - { - client_need_arrange(c); - c->isminimized = true; - } + client_setminimized(c, true); } else if(ev->type == _XEMBED) return xembed_process_client_message(ev); diff --git a/ewmh.c b/ewmh.c index 10d116246..51fb6d167 100644 --- a/ewmh.c +++ b/ewmh.c @@ -261,11 +261,20 @@ ewmh_process_state_atom(client_t *c, xcb_atom_t state, int set) else if(state == _NET_WM_STATE_SKIP_TASKBAR) { if(set == _NET_WM_STATE_REMOVE) + { c->skiptb = false; + ewmh_client_update_hints(c); + } else if(set == _NET_WM_STATE_ADD) + { c->skiptb = true; + ewmh_client_update_hints(c); + } else if(set == _NET_WM_STATE_TOGGLE) + { c->skiptb = !c->skiptb; + ewmh_client_update_hints(c); + } } else if(state == _NET_WM_STATE_FULLSCREEN) { @@ -306,23 +315,11 @@ ewmh_process_state_atom(client_t *c, xcb_atom_t state, int set) else if(state == _NET_WM_STATE_HIDDEN) { if(set == _NET_WM_STATE_REMOVE) - { - client_need_arrange(c); - c->isminimized = false; - client_need_arrange(c); - } + client_setminimized(c, false); else if(set == _NET_WM_STATE_ADD) - { - client_need_arrange(c); - c->isminimized = true; - client_need_arrange(c); - } + client_setminimized(c, true); else if(set == _NET_WM_STATE_TOGGLE) - { - client_need_arrange(c); - c->isminimized = !c->isminimized; - client_need_arrange(c); - } + client_setminimized(c, !c->isminimized); } else if(state == _NET_WM_STATE_DEMANDS_ATTENTION) { @@ -389,8 +386,38 @@ ewmh_process_client_message(xcb_client_message_event_t *ev) return 0; } +/** Update client EWMH hints. + * \param c The client. + */ void -ewmh_check_client_hints(client_t *c) +ewmh_client_update_hints(client_t *c) +{ + xcb_atom_t state[8]; /* number of defined state atoms */ + int i = 0; + + if(c->ismodal) + state[i++] = _NET_WM_STATE_MODAL; + if(c->isfullscreen) + state[i++] = _NET_WM_STATE_FULLSCREEN; + if(c->issticky) + state[i++] = _NET_WM_STATE_STICKY; + if(c->skiptb) + state[i++] = _NET_WM_STATE_SKIP_TASKBAR; + if(c->isabove) + state[i++] = _NET_WM_STATE_ABOVE; + if(c->isbelow) + state[i++] = _NET_WM_STATE_BELOW; + if(c->isminimized) + state[i++] = _NET_WM_STATE_HIDDEN; + if(c->isurgent) + state[i++] = _NET_WM_STATE_DEMANDS_ATTENTION; + + xcb_change_property(globalconf.connection, XCB_PROP_MODE_REPLACE, + c->win, _NET_WM_STATE, ATOM, 32, i, state); +} + +void +ewmh_client_check_hints(client_t *c) { xcb_atom_t *state; void *data = NULL; @@ -515,7 +542,6 @@ ewmh_client_strut_update(client_t *c, xcb_get_property_reply_t *strut_r) p_delete(&mstrut_r); } - /** Send request to get NET_WM_ICON (EWMH) * \param w The window. * \return The cookie associated with the request. diff --git a/ewmh.h b/ewmh.h index aa219b5bd..bbfd2a73c 100644 --- a/ewmh.h +++ b/ewmh.h @@ -32,7 +32,8 @@ void ewmh_update_net_desktop_names(int); void ewmh_update_net_active_window(int); int ewmh_process_client_message(xcb_client_message_event_t *); void ewmh_update_net_client_list_stacking(int); -void ewmh_check_client_hints(client_t *); +void ewmh_client_check_hints(client_t *); +void ewmh_client_update_hints(client_t *); void ewmh_update_workarea(int); void ewmh_client_strut_update(client_t *, xcb_get_property_reply_t *); xcb_get_property_cookie_t ewmh_window_icon_get_unchecked(xcb_window_t);