[focus] Rewrite focus handling on arrange.
Also add some documentation. Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
e710cff383
commit
495b99f1c5
|
@ -386,7 +386,7 @@ main(int argc, char **argv)
|
||||||
/* init screens struct */
|
/* init screens struct */
|
||||||
globalconf.screens_info = screensinfo_new(globalconf.connection);
|
globalconf.screens_info = screensinfo_new(globalconf.connection);
|
||||||
globalconf.screens = p_new(VirtScreen, globalconf.screens_info->nscreen);
|
globalconf.screens = p_new(VirtScreen, globalconf.screens_info->nscreen);
|
||||||
focus_add_client(NULL);
|
focus_client_push(NULL);
|
||||||
|
|
||||||
/* parse config */
|
/* parse config */
|
||||||
if(!confpath)
|
if(!confpath)
|
||||||
|
|
9
client.c
9
client.c
|
@ -204,7 +204,7 @@ client_unfocus(client_t *c)
|
||||||
luaA_settype(globalconf.L, "client");
|
luaA_settype(globalconf.L, "client");
|
||||||
luaA_dofunction(globalconf.L, globalconf.hooks.unfocus, 1);
|
luaA_dofunction(globalconf.L, globalconf.hooks.unfocus, 1);
|
||||||
|
|
||||||
focus_add_client(NULL);
|
focus_client_push(NULL);
|
||||||
widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS);
|
widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS);
|
||||||
titlebar_draw(c);
|
titlebar_draw(c);
|
||||||
}
|
}
|
||||||
|
@ -254,7 +254,7 @@ client_focus(client_t *c, int screen, bool raise)
|
||||||
/* unban the client before focusing or it will fail */
|
/* unban the client before focusing or it will fail */
|
||||||
client_unban(c);
|
client_unban(c);
|
||||||
/* save sel in focus history */
|
/* save sel in focus history */
|
||||||
focus_add_client(c);
|
focus_client_push(c);
|
||||||
titlebar_draw(c);
|
titlebar_draw(c);
|
||||||
xcb_set_input_focus(globalconf.connection, XCB_INPUT_FOCUS_POINTER_ROOT,
|
xcb_set_input_focus(globalconf.connection, XCB_INPUT_FOCUS_POINTER_ROOT,
|
||||||
c->win, XCB_CURRENT_TIME);
|
c->win, XCB_CURRENT_TIME);
|
||||||
|
@ -421,7 +421,10 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, int screen)
|
||||||
window_setshape(c->win, c->phys_screen);
|
window_setshape(c->win, c->phys_screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Push client in client list */
|
||||||
client_list_push(&globalconf.clients, c);
|
client_list_push(&globalconf.clients, c);
|
||||||
|
/* Append client in history: it'll be last. */
|
||||||
|
focus_client_append(c);
|
||||||
|
|
||||||
widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS);
|
widget_invalidate_cache(c->screen, WIDGET_CACHE_CLIENTS);
|
||||||
ewmh_update_net_client_list(c->phys_screen);
|
ewmh_update_net_client_list(c->phys_screen);
|
||||||
|
@ -643,7 +646,7 @@ client_unmanage(client_t *c)
|
||||||
|
|
||||||
/* remove client everywhere */
|
/* remove client everywhere */
|
||||||
client_list_detach(&globalconf.clients, c);
|
client_list_detach(&globalconf.clients, c);
|
||||||
focus_delete_client(c);
|
focus_client_delete(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);
|
||||||
|
|
||||||
|
|
41
focus.c
41
focus.c
|
@ -25,6 +25,10 @@
|
||||||
|
|
||||||
extern AwesomeConf globalconf;
|
extern AwesomeConf globalconf;
|
||||||
|
|
||||||
|
/** Get the client's node focus.
|
||||||
|
* \param c The client.
|
||||||
|
* \return The client node focus.
|
||||||
|
*/
|
||||||
static client_node_t *
|
static client_node_t *
|
||||||
focus_get_node_by_client(client_t *c)
|
focus_get_node_by_client(client_t *c)
|
||||||
{
|
{
|
||||||
|
@ -37,8 +41,12 @@ focus_get_node_by_client(client_t *c)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
/** Create a client node for focus.
|
||||||
focus_add_client(client_t *c)
|
* \param c The client
|
||||||
|
* \return The client focus node.
|
||||||
|
*/
|
||||||
|
static client_node_t *
|
||||||
|
focus_client_add(client_t *c)
|
||||||
{
|
{
|
||||||
client_node_t *node;
|
client_node_t *node;
|
||||||
|
|
||||||
|
@ -51,11 +59,34 @@ focus_add_client(client_t *c)
|
||||||
else /* if we've got a node, detach it */
|
else /* if we've got a node, detach it */
|
||||||
client_node_list_detach(&globalconf.focus, node);
|
client_node_list_detach(&globalconf.focus, node);
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Push the client at the beginning of the client focus history stack.
|
||||||
|
* \param c The client to push.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
focus_client_push(client_t *c)
|
||||||
|
{
|
||||||
|
client_node_t *node = focus_client_add(c);
|
||||||
client_node_list_push(&globalconf.focus, node);
|
client_node_list_push(&globalconf.focus, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Append the client at the end of the client focus history stack.
|
||||||
|
* \param c The client to append.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
focus_delete_client(client_t *c)
|
focus_client_append(client_t *c)
|
||||||
|
{
|
||||||
|
client_node_t *node = focus_client_add(c);
|
||||||
|
client_node_list_append(&globalconf.focus, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Remove a client from focus history.
|
||||||
|
* \param c The client.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
focus_client_delete(client_t *c)
|
||||||
{
|
{
|
||||||
client_node_t *node = focus_get_node_by_client(c);
|
client_node_t *node = focus_get_node_by_client(c);
|
||||||
|
|
||||||
|
@ -87,6 +118,10 @@ focus_get_latest_client_for_tags(tag_t **t, int nindex)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Get the latest focused client on a screen.
|
||||||
|
* \param screen The virtual screen number.
|
||||||
|
* \return A pointer to an existing client.
|
||||||
|
*/
|
||||||
client_t *
|
client_t *
|
||||||
focus_get_current_client(int screen)
|
focus_get_current_client(int screen)
|
||||||
{
|
{
|
||||||
|
|
5
focus.h
5
focus.h
|
@ -24,8 +24,9 @@
|
||||||
|
|
||||||
#include "structs.h"
|
#include "structs.h"
|
||||||
|
|
||||||
void focus_add_client(client_t *);
|
void focus_client_push(client_t *);
|
||||||
void focus_delete_client(client_t *);
|
void focus_client_append(client_t *);
|
||||||
|
void focus_client_delete(client_t *);
|
||||||
client_t * focus_get_current_client(int);
|
client_t * focus_get_current_client(int);
|
||||||
|
|
||||||
DO_SLIST(client_node_t, client_node, p_delete)
|
DO_SLIST(client_node_t, client_node, p_delete)
|
||||||
|
|
22
layout.c
22
layout.c
|
@ -44,7 +44,7 @@ arrange(int screen)
|
||||||
{
|
{
|
||||||
client_t *c;
|
client_t *c;
|
||||||
layout_t *curlay = layout_get_current(screen);
|
layout_t *curlay = layout_get_current(screen);
|
||||||
int phys_screen = screen_virttophys(screen);
|
int fscreen, phys_screen = screen_virttophys(screen);
|
||||||
xcb_query_pointer_cookie_t qp_c;
|
xcb_query_pointer_cookie_t qp_c;
|
||||||
xcb_query_pointer_reply_t *qp_r;
|
xcb_query_pointer_reply_t *qp_r;
|
||||||
|
|
||||||
|
@ -67,11 +67,6 @@ arrange(int screen)
|
||||||
client_unban(c);
|
client_unban(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we have a valid client that could be focused but currently no window
|
|
||||||
* are focused, then set the focus on this window */
|
|
||||||
if((c = focus_get_current_client(screen)) && !globalconf.focus->client)
|
|
||||||
client_focus(c, screen, true);
|
|
||||||
|
|
||||||
qp_c = xcb_query_pointer_unchecked(globalconf.connection,
|
qp_c = xcb_query_pointer_unchecked(globalconf.connection,
|
||||||
xcb_aux_get_screen(globalconf.connection,
|
xcb_aux_get_screen(globalconf.connection,
|
||||||
phys_screen)->root);
|
phys_screen)->root);
|
||||||
|
@ -84,6 +79,21 @@ arrange(int screen)
|
||||||
|
|
||||||
globalconf.pointer_x = qp_r->root_x;
|
globalconf.pointer_x = qp_r->root_x;
|
||||||
globalconf.pointer_y = qp_r->root_y;
|
globalconf.pointer_y = qp_r->root_y;
|
||||||
|
|
||||||
|
/* no window have focus, let's try to see if mouse is on
|
||||||
|
* the screen we just rearranged */
|
||||||
|
if(!globalconf.focus->client)
|
||||||
|
{
|
||||||
|
fscreen = screen_get_bycoord(globalconf.screens_info,
|
||||||
|
screen,
|
||||||
|
qp_r->root_x, qp_r->root_y);
|
||||||
|
/* if the mouse in on the same screen we just rearranged, and no
|
||||||
|
* client are currently focused, pick the first one in history */
|
||||||
|
if(fscreen == screen
|
||||||
|
&& (c = focus_get_current_client(screen)))
|
||||||
|
client_focus(c, screen, true);
|
||||||
|
}
|
||||||
|
|
||||||
p_delete(&qp_r);
|
p_delete(&qp_r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue