BUG's page
[awesome.git] / focus.c
blob90e924d30b71e69e40e0ed0e823fa6f26955311c
1 /*
2 * focus.c - focus management
4 * Copyright © 2007-2008 Julien Danjou <julien@danjou.info>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "tag.h"
23 #include "focus.h"
24 #include "client.h"
26 extern AwesomeConf globalconf;
28 static client_node_t *
29 focus_get_node_by_client(Client *c)
31 client_node_t *node;
33 for(node = globalconf.focus; node; node = node->next)
34 if(node->client == c)
35 return node;
37 return NULL;
40 void
41 focus_add_client(Client *c)
43 client_node_t *node;
45 /* if we don't find this node, create a new one */
46 if(!(node = focus_get_node_by_client(c)))
48 node = p_new(client_node_t, 1);
49 node->client = c;
51 else /* if we've got a node, detach it */
52 client_node_list_detach(&globalconf.focus, node);
54 client_node_list_push(&globalconf.focus, node);
57 void
58 focus_delete_client(Client *c)
60 client_node_t *node = focus_get_node_by_client(c);
62 if(node)
64 client_node_list_detach(&globalconf.focus, node);
65 p_delete(&node);
69 static Client *
70 focus_get_latest_client_for_tags(Tag **t, int nindex)
72 client_node_t *node;
73 Tag **tags;
74 int i = 0;
76 for(node = globalconf.focus; node; node = node->next)
77 if(node->client && ((!node->client->skip
78 && node->client != globalconf.scratch.client)
79 || globalconf.scratch.isvisible))
80 for(tags = t; *tags; tags++)
81 if(is_client_tagged(node->client, *tags))
83 if(i == nindex)
84 return node->client;
85 else
86 i--;
89 return NULL;
92 Client *
93 focus_get_current_client(int screen)
95 Tag **curtags = tags_get_current(screen);
96 Client *sel = focus_get_latest_client_for_tags(curtags, 0);
97 p_delete(&curtags);
99 return sel;
102 /** Jump back in the focus history stack.
103 * Set arg to 0 for previous, -1 for previous of previous, etc.
104 * \param screen Screen ID
105 * \param arg Integer argument
106 * \ingroup ui_callback
108 void
109 uicb_focus_history(int screen, char *arg)
111 int i;
112 Tag **curtags;
113 Client *c;
115 if(arg)
117 i = atoi(arg);
119 if(i < 0)
121 curtags = tags_get_current(screen);
122 c = focus_get_latest_client_for_tags(curtags, i);
123 p_delete(&curtags);
124 if(c)
125 client_focus(c, screen, True);
130 /** Focus one of the visible clients by its name.
131 * \param screen screen id
132 * \param arg client's name
133 * \ingroup ui_callback
135 void
136 uicb_focus_client_byname(int screen, char *arg)
138 Client *c;
139 Tag **curtags, **tag;
141 if(arg)
143 curtags = tags_get_current(screen);
144 if((c = client_get_byname(globalconf.clients, arg)))
145 for(tag = curtags; *tag; tag++)
146 if(is_client_tagged(c, *tag))
147 client_focus(c, screen, True);
148 p_delete(&curtags);
152 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80