use lists functions for Client

This commit is contained in:
Julien Danjou 2008-01-12 17:01:21 +01:00
parent 771199a2e5
commit 572f409a29
4 changed files with 42 additions and 107 deletions

125
client.c
View File

@ -102,40 +102,6 @@ isprotodel(Display *disp, Window win)
return ret; return ret;
} }
/** Swap two client in the linked list clients
* \param head pointer ito the client list head
* \param c1 first client
* \param c2 second client
*/
static void
client_swap(Client **head, Client *c1, Client *c2)
{
Client *tmp;
tmp = c1->next;
c1->next = c2->next;
c2->next = (tmp == c2 ? c1 : tmp);
tmp = c2->prev;
c2->prev = c1->prev;
c1->prev = (tmp == c1 ? c2 : tmp );
if(c1->next)
c1->next->prev = c1;
if(c1->prev)
c1->prev->next = c1;
if(c2->next)
c2->next->prev = c2;
if(c2->prev)
c2->prev->next = c2;
if(*head == c1)
*head = c2;
}
/** Get a Client by its window /** Get a Client by its window
* \param list Client list to look info * \param list Client list to look info
* \param w Client window to find * \param w Client window to find
@ -150,7 +116,6 @@ get_client_bywin(Client *list, Window w)
return c; return c;
} }
/** Get a client by its name /** Get a client by its name
* \param list Client list * \param list Client list
* \param name name to search * \param name name to search
@ -190,49 +155,6 @@ client_ban(Client * c)
window_setstate(c->win, IconicState); window_setstate(c->win, IconicState);
} }
static void
client_attach_at_end(Client *c)
{
Client *iter;
for(iter = globalconf.clients; iter && iter->next; iter = iter->next);
/* stack is empty */
if(!iter)
globalconf.clients = c;
else
{
c->prev = iter;
iter->next = c;
}
}
/** Attach client to the beginning of the clients stack
* \param c the client
*/
void
client_attach(Client *c)
{
if(globalconf.clients)
(globalconf.clients)->prev = c;
c->next = globalconf.clients;
globalconf.clients = c;
}
/** Detach client from clients list
* \param c client to detach
*/
void
client_detach(Client *c)
{
if(c->prev)
c->prev->next = c->next;
if(c->next)
c->next->prev = c->prev;
if(c == globalconf.clients)
globalconf.clients = c->next;
c->next = c->prev = NULL;
}
/** Give focus to client, or to first client if c is NULL /** Give focus to client, or to first client if c is NULL
* \param c client * \param c client
* \param selscreen True if current screen is selected * \param selscreen True if current screen is selected
@ -408,15 +330,15 @@ client_manage(Window w, XWindowAttributes *wa, int screen)
for(rule = globalconf.rules; rule; rule = rule->next) for(rule = globalconf.rules; rule; rule = rule->next)
if(rule->not_master && client_match_rule(c, rule)) if(rule->not_master && client_match_rule(c, rule))
{ {
client_attach_at_end(c); client_list_append(&globalconf.clients, c);
break; break;
} }
if(!rule) if(!rule)
{ {
if(globalconf.screens[c->screen].new_become_master) if(globalconf.screens[c->screen].new_become_master)
client_attach(c); client_list_push(&globalconf.clients, c);
else else
client_attach_at_end(c); client_list_append(&globalconf.clients, c);
} }
ewmh_update_net_client_list(phys_screen); ewmh_update_net_client_list(phys_screen);
@ -587,7 +509,7 @@ client_unmanage(Client *c)
XConfigureWindow(globalconf.display, c->win, CWBorderWidth, &wc); /* restore border */ XConfigureWindow(globalconf.display, c->win, CWBorderWidth, &wc); /* restore border */
/* remove client everywhere */ /* remove client everywhere */
client_detach(c); client_list_detach(&globalconf.clients, c);
focus_delete_client(c); focus_delete_client(c);
for(tag = globalconf.screens[c->screen].tags; tag; tag = tag->next) for(tag = globalconf.screens[c->screen].tags; tag; tag = tag->next)
untag_client(c, tag); untag_client(c, tag);
@ -770,11 +692,34 @@ uicb_client_swapnext(int screen, char *arg __attribute__ ((unused)))
for(next = sel->next; next && !client_isvisible(next, screen); next = next->next); for(next = sel->next; next && !client_isvisible(next, screen); next = next->next);
if(next) if(next)
{ {
client_swap(&globalconf.clients, sel, next); client_list_swap(&globalconf.clients, sel, next);
arrange(screen); arrange(screen);
} }
} }
Client *
client_find_prev_visible(Client *sel)
{
Client *prev = NULL;
if(!sel) return NULL;
/* look for previous starting at sel */
for(prev = client_list_prev(&globalconf.clients, sel);
prev && (prev->skip || !client_isvisible(prev, sel->screen));
prev = client_list_prev(&globalconf.clients, prev));
/* look for previous starting at the end of the list */
if(!prev || prev->skip || !client_isvisible(prev, sel->screen))
for(prev = *client_list_last(&globalconf.clients);
prev && prev != sel
&& (prev->skip || !client_isvisible(prev, sel->screen));
prev = client_list_prev(&globalconf.clients, prev));
return prev;
}
/** Swap current with previous client /** Swap current with previous client
* \param screen Screen ID * \param screen Screen ID
* \param arg nothing * \param arg nothing
@ -783,15 +728,11 @@ uicb_client_swapnext(int screen, char *arg __attribute__ ((unused)))
void void
uicb_client_swapprev(int screen, char *arg __attribute__ ((unused))) uicb_client_swapprev(int screen, char *arg __attribute__ ((unused)))
{ {
Client *prev, *sel = globalconf.focus->client; Client *prev;
if(!sel) if((prev = client_find_prev_visible(globalconf.focus->client)))
return;
for(prev = sel->prev; prev && !client_isvisible(prev, screen); prev = prev->prev);
if(prev)
{ {
client_swap(&globalconf.clients, prev, sel); client_list_swap(&globalconf.clients, prev, globalconf.focus->client);
arrange(screen); arrange(screen);
} }
} }
@ -999,8 +940,8 @@ uicb_client_zoom(int screen, char *arg __attribute__ ((unused)))
if(!sel) if(!sel)
return; return;
client_detach(sel); client_list_detach(&globalconf.clients, sel);
client_attach(sel); client_list_push(&globalconf.clients, sel);
arrange(screen); arrange(screen);
} }

View File

@ -27,8 +27,7 @@
Bool client_isvisible(Client *, int); Bool client_isvisible(Client *, int);
Client * get_client_bywin(Client *, Window); Client * get_client_bywin(Client *, Window);
Client * get_client_byname(Client *, char *); Client * get_client_byname(Client *, char *);
void client_attach(Client *); Client * client_find_prev_visible(Client *);
void client_detach(Client *);
void client_ban(Client *); void client_ban(Client *);
void focus(Client *, Bool, int); void focus(Client *, Bool, int);
void client_manage(Window, XWindowAttributes *, int); void client_manage(Window, XWindowAttributes *, int);

View File

@ -25,6 +25,8 @@
#include <regex.h> #include <regex.h>
#include "draw.h" #include "draw.h"
#include "layout.h" #include "layout.h"
#include "util.h"
#include "list.h"
/** Bar possible position */ /** Bar possible position */
typedef enum typedef enum
@ -181,8 +183,6 @@ struct Client
Bool skiptb; Bool skiptb;
/** Next client */ /** Next client */
Client *next; Client *next;
/** Previous client */
Client *prev;
/** Window of the client */ /** Window of the client */
Window win; Window win;
/** Client logical screen */ /** Client logical screen */
@ -191,6 +191,9 @@ struct Client
Bool newcomer; Bool newcomer;
}; };
DO_SLIST(Client, client, p_delete);
typedef struct FocusList FocusList; typedef struct FocusList FocusList;
struct FocusList struct FocusList
{ {

View File

@ -128,19 +128,11 @@ uicb_client_focusnext(int screen, char *arg __attribute__ ((unused)))
void void
uicb_client_focusprev(int screen, char *arg __attribute__ ((unused))) uicb_client_focusprev(int screen, char *arg __attribute__ ((unused)))
{ {
Client *c, *sel = globalconf.focus->client; Client *prev;
if(!sel) if((prev = client_find_prev_visible(globalconf.focus->client)))
return;
for(c = sel->prev; c && (c->skip || !client_isvisible(c, screen)); c = c->prev);
if(!c)
{ {
for(c = globalconf.clients; c && c->next; c = c->next); focus(prev, True, screen);
for(; c && (c->skip || !client_isvisible(c, screen)); c = c->prev);
}
if(c)
{
focus(c, True, screen);
restack(screen); restack(screen);
} }
} }