diff --git a/Makefile.am b/Makefile.am index 20300b95..24412665 100644 --- a/Makefile.am +++ b/Makefile.am @@ -115,6 +115,7 @@ awesome_SOURCES = \ titlebar.c titlebar.h \ placement.c placement.h \ focus.c focus.h \ + stack.c stack.h \ cnode.c cnode.h \ event.c event.h \ layout.c layout.h \ diff --git a/client.c b/client.c index b87ab153..0b469772 100644 --- a/client.c +++ b/client.c @@ -35,6 +35,7 @@ #include "screen.h" #include "titlebar.h" #include "lua.h" +#include "stack.h" #include "layouts/floating.h" #include "common/markup.h" #include "common/xutil.h" @@ -286,53 +287,41 @@ client_focus(client_t *c, int screen, bool raise) return true; } +/** Restack clients and puts c in top of its layer. + * \param c The client to stack on top of others. + * \todo It might be worth stopping to restack everyone and only stack `c' + * relatively to the first matching in the list + */ void client_stack(client_t *c) { uint32_t config_win_vals[2]; - client_t *client; + client_node_t *node; layer_t layer; config_win_vals[0] = XCB_NONE; - config_win_vals[1] = XCB_STACK_MODE_ABOVE; + config_win_vals[1] = XCB_STACK_MODE_BELOW; - for(layer = LAYER_DESKTOP; layer < LAYER_FULLSCREEN; layer++) - { - /* \todo we need to maintain a separate stack list */ - for(client = globalconf.clients; client; client = client->next) - { - if(client->layer == layer && client != c - && client_isvisible_anyscreen(client)) + stack_client_push(c); + + for(layer = LAYER_FULLSCREEN; layer >= LAYER_DESKTOP; layer--) + for(node = globalconf.stack; node; node = node->next) + if(node->client->layer == layer + && client_isvisible_anyscreen(node->client)) { - if(client->titlebar.position && client->titlebar_sw) + if(node->client->titlebar.position && node->client->titlebar_sw) { xcb_configure_window(globalconf.connection, - client->titlebar_sw->window, + node->client->titlebar_sw->window, XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE, config_win_vals); - config_win_vals[0] = client->titlebar_sw->window; + config_win_vals[0] = node->client->titlebar_sw->window; } - xcb_configure_window(globalconf.connection, client->win, + xcb_configure_window(globalconf.connection, node->client->win, XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE, config_win_vals); - config_win_vals[0] = client->win; + config_win_vals[0] = node->client->win; } - } - if(c->layer == layer) - { - if(c->titlebar.position && c->titlebar_sw) - { - xcb_configure_window(globalconf.connection, c->titlebar_sw->window, - XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE, - config_win_vals); - config_win_vals[0] = c->titlebar_sw->window; - } - xcb_configure_window(globalconf.connection, c->win, - XCB_CONFIG_WINDOW_SIBLING | XCB_CONFIG_WINDOW_STACK_MODE, - config_win_vals); - config_win_vals[0] = c->win; - } - } } /** Manage a new client @@ -653,6 +642,7 @@ client_unmanage(client_t *c) /* remove client everywhere */ client_list_detach(&globalconf.clients, c); focus_client_delete(c); + stack_client_delete(c); for(tag = globalconf.screens[c->screen].tags; tag; tag = tag->next) untag_client(c, tag); diff --git a/stack.c b/stack.c new file mode 100644 index 00000000..3e8a0dc8 --- /dev/null +++ b/stack.c @@ -0,0 +1,52 @@ +/* + * stack.c - client stack management + * + * Copyright © 2008 Julien Danjou + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include "stack.h" +#include "cnode.h" + +extern awesome_t globalconf; + +/** Push the client at the beginning of the client stack history stack. + * \param c The client to push. + */ +void +stack_client_push(client_t *c) +{ + client_node_t *node = client_node_client_add(&globalconf.stack, c); + client_node_list_push(&globalconf.stack, node); +} + +/** Remove a client from stack history. + * \param c The client. + */ +void +stack_client_delete(client_t *c) +{ + client_node_t *node = client_node_client_getby(globalconf.stack, c); + + if(node) + { + client_node_list_detach(&globalconf.stack, node); + p_delete(&node); + } +} + +// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/stack.h b/stack.h new file mode 100644 index 00000000..1cf54390 --- /dev/null +++ b/stack.h @@ -0,0 +1,31 @@ +/* + * stack.h - client stack management header + * + * Copyright © 2007-2008 Julien Danjou + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef AWESOME_STACK_H +#define AWESOME_STACK_H + +#include "structs.h" + +void stack_client_push(client_t *); +void stack_client_delete(client_t *); + +#endif +// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80 diff --git a/structs.h b/structs.h index 8567b990..4e66b710 100644 --- a/structs.h +++ b/structs.h @@ -34,7 +34,7 @@ /** Stacking layout layers */ typedef enum { - LAYER_DESKTOP, + LAYER_DESKTOP = 1, LAYER_BELOW, LAYER_TILE, LAYER_FLOAT, @@ -387,6 +387,8 @@ struct awesome_t FloatingPlacement *floating_placement; /** Selected clients history */ client_node_t *focus; + /** Stack client history */ + client_node_t *stack; /** Link between tags and clients */ tag_client_node_t *tclink; /** Command line passed to awesome */