From 9067f3cb6626bca077ea68bc186a0651c2c7f418 Mon Sep 17 00:00:00 2001 From: Martin Duquesnoy Date: Sun, 6 Jun 2010 22:48:25 +0200 Subject: [PATCH] Client: Add focus traveling with uicb function: client_focus_{right, left, top, bottom} (Feature #45 requested by biiter) [NEED TEST] --- src/client.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/config.c | 4 ++ src/wmfs.h | 5 +++ 3 files changed, 121 insertions(+) diff --git a/src/client.c b/src/client.c index 355429e..4cc1652 100644 --- a/src/client.c +++ b/src/client.c @@ -127,6 +127,49 @@ client_get_prev(void) return c; } +/** Get client left/right/top/bottom of selected client + *\param pos Position (Left/Right/Top/Bottom + *\return Client found +*/ +Client* +client_get_next_with_direction(Position pos) +{ + Client *c = NULL; + Client *ret = NULL; + + if(!sel || ishide(sel, selscreen)) + return NULL; + + for(c = clients; c; c = c->next) + if(c != sel && !ishide(c, sel->screen)) + switch(pos) + { + default: + case Right: + if(c->geo.x > sel->geo.x + && (!ret || (ret && ret->geo.x > sel->geo.x && c->geo.x < ret->geo.x))) + ret = c; + break; + case Left: + if(c->geo.x < sel->geo.x + && (!ret || (ret && ret->geo.x < sel->geo.x && c->geo.x > ret->geo.x))) + ret = c; + break; + case Top: + if(c->geo.y < sel->geo.y + && (!ret || (ret && ret->geo.y < sel->geo.y && c->geo.y > ret->geo.y))) + ret = c; + break; + case Bottom: + if(c->geo.y > sel->geo.y + && (!ret || (ret && ret->geo.y > sel->geo.y && c->geo.y < ret->geo.y))) + ret = c; + break; + } + + return ret; +} + /** Switch to the previous client * \param cmd uicb_t type unused */ @@ -195,6 +238,75 @@ uicb_client_swap_prev(uicb_t cmd) return; } +/** Select next client positioned to the right + *\param cmd uicb_t type unused +*/ +void +uicb_client_focus_right(uicb_t cmd) +{ + Client *c; + + if((c = client_get_next_with_direction(Right))) + { + client_focus(c); + client_raise(c); + + } + + return; +} + +/** Select next client positioned to the left + *\param cmd uicb_t type unused +*/ +void +uicb_client_focus_left(uicb_t cmd) +{ + Client *c; + + if((c = client_get_next_with_direction(Left))) + { + client_focus(c); + client_raise(c); + } + + return; +} + +/** Select next client positioned to the top + *\param cmd uicb_t type unused +*/ +void +uicb_client_focus_top(uicb_t cmd) +{ + Client *c; + + if((c = client_get_next_with_direction(Top))) + { + client_focus(c); + client_raise(c); + } + + return; +} + +/** Select next client positioned to the bottom + *\param cmd uicb_t type unused +*/ +void +uicb_client_focus_bottom(uicb_t cmd) +{ + Client *c; + + if((c = client_get_next_with_direction(Bottom))) + { + client_focus(c); + client_raise(c); + } + + return; +} + /** Set the client c above *\param c Client pointer */ diff --git a/src/config.c b/src/config.c index 6ccace5..49b6846 100644 --- a/src/config.c +++ b/src/config.c @@ -42,6 +42,10 @@ func_name_list_t tmp_func_list[] = {"client_swap_prev", uicb_client_swap_prev }, {"client_screen_next", uicb_client_screen_next }, {"client_screen_prev", uicb_client_screen_prev }, + {"client_focus_right", uicb_client_focus_right }, + {"client_focus_left" , uicb_client_focus_left }, + {"client_focus_top", uicb_client_focus_top }, + {"client_focus_bottom", uicb_client_focus_bottom }, {"client_move", uicb_client_move }, {"client_resize", uicb_client_resize }, {"client_ignore_tag", uicb_client_ignore_tag }, diff --git a/src/wmfs.h b/src/wmfs.h index c2344df..40b3509 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -164,6 +164,7 @@ void client_above(Client *c); void client_focus(Client *c); Client* client_get_next(void); Client* client_get_prev(void); +Client* client_get_next_with_direction(Position pos); /* client_gb_*() {{{ */ Client* client_gb_win(Window w); Client* client_gb_frame(Window w); @@ -193,6 +194,10 @@ void uicb_client_next(uicb_t); void uicb_client_prev(uicb_t); void uicb_client_swap_next(uicb_t); void uicb_client_swap_prev(uicb_t); +void uicb_client_focus_right(uicb_t cmd); +void uicb_client_focus_left(uicb_t cmd); +void uicb_client_focus_top(uicb_t cmd); +void uicb_client_focus_bottom(uicb_t cmd); void uicb_client_kill(uicb_t); void uicb_client_screen_next(uicb_t); void uicb_client_screen_prev(uicb_t);