diff --git a/wmfs2/src/client.c b/wmfs2/src/client.c index f074852..12297a8 100644 --- a/wmfs2/src/client.c +++ b/wmfs2/src/client.c @@ -15,11 +15,27 @@ #define CLIENT_MOUSE_MOD Mod1Mask -#define CLIENT_RESIZE_DIR(d) \ -void uicb_client_resize_##d(Uicb cmd) \ +#define CLIENT_RESIZE_DIR(D) \ +void uicb_client_resize_##D(Uicb cmd) \ { \ if(W->client) \ - client_fac_resize(W->client, d, ATOI(cmd)); \ + client_fac_resize(W->client, D, ATOI(cmd)); \ +} + +#define CLIENT_ACTION_DIR(A, D) \ +void uicb_client_##A##_##D(Uicb cmd) \ +{ \ + (void)cmd; \ + if(W->client) \ + client_##A(client_next_with_pos(W->client, D)); \ +} + +#define CLIENT_ACTION_LIST(A, L) \ +void uicb_client_##A##_##L(Uicb cmd) \ +{ \ + (void)cmd; \ + if(W->client) \ + client_##A(client_##L(W->client)); \ } /* uicb_client_resize_dir() */ @@ -28,6 +44,27 @@ CLIENT_RESIZE_DIR(Left) CLIENT_RESIZE_DIR(Top) CLIENT_RESIZE_DIR(Bottom) +/* uicb_client_focus_dir() */ +CLIENT_ACTION_DIR(focus, Right) +CLIENT_ACTION_DIR(focus, Left) +CLIENT_ACTION_DIR(focus, Top) +CLIENT_ACTION_DIR(focus, Bottom) + +/* uicb_client_swapsel_dir() */ +#define client_swapsel(c) client_swap(W->client, c) +CLIENT_ACTION_DIR(swapsel, Right) +CLIENT_ACTION_DIR(swapsel, Left) +CLIENT_ACTION_DIR(swapsel, Top) +CLIENT_ACTION_DIR(swapsel, Bottom) + +/* uicb_client_focus_next/prev() */ +CLIENT_ACTION_LIST(focus, next) +CLIENT_ACTION_LIST(focus, prev) + +/* uicb_client_swapsel_next/prev() */ +CLIENT_ACTION_LIST(swapsel, next) +CLIENT_ACTION_LIST(swapsel, prev) + /** Send a ConfigureRequest event to the struct client * \param c struct client pointer */ @@ -52,6 +89,29 @@ client_configure(struct client *c) XSync(W->dpy, False); } +struct client* +client_next(struct client *c) +{ + struct client *next; + + if(!(next = SLIST_NEXT(c, tnext))) + next = SLIST_FIRST(&c->tag->clients); + + return next; +} + +struct client* +client_prev(struct client *c) +{ + struct client *cc; + + SLIST_FOREACH(cc, &c->tag->clients, tnext) + if(SLIST_NEXT(cc, tnext) == c || !SLIST_NEXT(cc, tnext)) + return cc; + + return SLIST_FIRST(&c->tag->clients); +} + struct client* client_gb_win(Window w) { @@ -111,6 +171,27 @@ client_next_with_pos(struct client *bc, Position p) return c; } +void +client_swap(struct client *c1, struct client *c2) +{ + struct tag *t; + struct geo g; + + if(c1 == c2 || !c1 || !c2) + return; + + t = c1->tag; + g = c1->geo; + + swap_ptr((void**)&c1->screen, (void**)&c2->screen); + + tag_client(c2->tag, c1); + tag_client(t, c2); + + client_moveresize(c1, c2->geo); + client_moveresize(c2, g); +} + static void client_grabbuttons(struct client *c, bool focused) { @@ -143,15 +224,15 @@ client_grabbuttons(struct client *c, bool focused) } static inline void -client_draw_bord(void) +client_draw_bord(struct client *c) { - struct geo g = { 0, 0, W->screen->ugeo.w, W->screen->ugeo.h }; + struct geo g = { 0, 0, c->screen->ugeo.w, c->screen->ugeo.h }; - draw_rect(W->screen->seltag->frame, g, THEME_DEFAULT->client_n.bg); + draw_rect(c->tag->frame, g, THEME_DEFAULT->client_n.bg); /* Selected client's border */ if(W->client) - draw_rect(W->client->tag->frame, W->client->geo, THEME_DEFAULT->client_s.bg); + draw_rect(c->tag->frame, c->tag->sel->geo, THEME_DEFAULT->client_s.bg); } @@ -167,9 +248,10 @@ client_focus(struct client *c) { c->tag->sel = c; - client_draw_bord(); - + client_draw_bord(c); client_grabbuttons(c, true); + + XSetInputFocus(W->dpy, c->win, RevertToPointerRoot, CurrentTime); } } @@ -286,19 +368,20 @@ client_moveresize(struct client *c, struct geo g) { int bord = THEME_DEFAULT->client_border_width; - c->geo = c->wgeo = g; + c->geo = g; /* Window geo */ - c->wgeo.x += bord; - c->wgeo.y += bord ; - c->wgeo.w -= (bord << 1); - c->wgeo.h -= (bord << 1); + c->wgeo.x = g.x + bord; + c->wgeo.y = g.y + bord ; + c->wgeo.w = g.w - (bord << 1); + c->wgeo.h = g.h - (bord << 1); XMoveResizeWindow(W->dpy, c->win, c->wgeo.x, c->wgeo.y, c->wgeo.w, c->wgeo.h); - client_draw_bord(); + client_draw_bord(c); + client_configure(c); } void diff --git a/wmfs2/src/client.h b/wmfs2/src/client.h index a49b233..3a295f9 100644 --- a/wmfs2/src/client.h +++ b/wmfs2/src/client.h @@ -10,9 +10,13 @@ #include "layout.h" void client_configure(struct client *c); + +struct client *client_next(struct client *c); +struct client *client_prev(struct client *c); struct client *client_gb_win(Window w); -struct client* client_gb_pos(struct tag *t, int x, int y); +struct client *client_gb_pos(struct tag *t, int x, int y); struct client *client_next_with_pos(struct client *bc, Position p); +void client_swap(struct client *c1, struct client *c2); void client_focus(struct client *c); void client_get_name(struct client *c); void client_close(struct client *c); @@ -23,10 +27,24 @@ void client_maximize(struct client *c); void client_fac_resize(struct client *c, Position p, int fac); void client_remove(struct client *c); void client_free(void); + +/* Generated */ void uicb_client_resize_Right(Uicb); void uicb_client_resize_Left(Uicb); void uicb_client_resize_Top(Uicb); void uicb_client_resize_Bottom(Uicb); +void uicb_client_focus_Right(Uicb); +void uicb_client_focus_Left(Uicb); +void uicb_client_focus_Top(Uicb); +void uicb_client_focus_Bottom(Uicb); +void uicb_client_swapsel_Right(Uicb); +void uicb_client_swapsel_Left(Uicb); +void uicb_client_swapsel_Top(Uicb); +void uicb_client_swapsel_Bottom(Uicb); +void uicb_client_focus_next(Uicb); +void uicb_client_focus_prev(Uicb); +void uicb_client_swapsel_next(Uicb); +void uicb_client_swapsel_prev(Uicb); static inline bool client_fac_geo(struct client *c, Position p, int fac) diff --git a/wmfs2/src/config.h b/wmfs2/src/config.h index 1e2140e..d106bf5 100644 --- a/wmfs2/src/config.h +++ b/wmfs2/src/config.h @@ -36,7 +36,18 @@ static const struct { char *name; void (*func)(Uicb cmd); } uicb_list[] = { "client_resize_left", uicb_client_resize_Left }, { "client_resize_top", uicb_client_resize_Top }, { "client_resize_bottom", uicb_client_resize_Bottom }, - + { "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_swap_right", uicb_client_swapsel_Right }, + { "client_swap_left", uicb_client_swapsel_Left }, + { "client_swap_top", uicb_client_swapsel_Top }, + { "client_swap_bottom", uicb_client_swapsel_Bottom }, + { "client_focus_next", uicb_client_focus_next }, + { "client_focus_prev", uicb_client_focus_prev }, + { "client_swap_next", uicb_client_swapsel_next }, + { "client_swap_prev", uicb_client_swapsel_prev }, { NULL, NULL } }; diff --git a/wmfs2/src/event.c b/wmfs2/src/event.c index ec5c144..d4af4b1 100644 --- a/wmfs2/src/event.c +++ b/wmfs2/src/event.c @@ -35,6 +35,7 @@ event_buttonpress(XEvent *e) } } +/* static void event_enternotify(XEvent *e) { @@ -48,12 +49,13 @@ event_enternotify(XEvent *e) if((c = client_gb_win(ev->window))) client_focus(c); } +*/ static void event_clientmessageevent(XEvent *e) { - /* XclientMessageEvent *ev = &e->xclient; - client *c;*/ + /* XClientMessageEvent *ev = &e->xclient; + client *c;*/ } static void @@ -184,15 +186,12 @@ event_unmapnotify(XEvent *e) static void event_motionnotify(XEvent *e) { - /* - XMotionEvent *ev = &e->xmotion; - client *c; + XMotionEvent *ev = &e->xmotion; + struct client *c; - - * Option follow mouvement - if((c = client_gb_win(ev->subwindow)) && c != c->tag->sel) - client_focus(c); - */ + /* Option follow mouvement */ + if((c = client_gb_win(ev->subwindow)) && c != c->tag->sel) + client_focus(c); } static void @@ -243,7 +242,7 @@ event_init(void) event_handle[ClientMessage] = event_clientmessageevent; event_handle[ConfigureRequest] = event_configureevent; event_handle[DestroyNotify] = event_destroynotify; - event_handle[EnterNotify] = event_enternotify; + /*event_handle[EnterNotify] = event_enternotify; use motion instead */ event_handle[Expose] = event_expose; event_handle[FocusIn] = event_focusin; event_handle[KeyPress] = event_keypress; diff --git a/wmfs2/src/screen.c b/wmfs2/src/screen.c index c320ef6..5aacbaa 100644 --- a/wmfs2/src/screen.c +++ b/wmfs2/src/screen.c @@ -13,6 +13,7 @@ #include "util.h" #include "tag.h" #include "infobar.h" +#include "client.h" static struct screen* screen_new(struct geo *g, int id) @@ -91,6 +92,8 @@ screen_update_sel(void) if(INAREA(x, y, s->geo)) break; + client_focus(s->seltag->sel); + return (W->screen = s); } #endif /* HAVE_XINERAMA */ diff --git a/wmfs2/src/util.h b/wmfs2/src/util.h index df751c6..9359bd7 100644 --- a/wmfs2/src/util.h +++ b/wmfs2/src/util.h @@ -44,6 +44,15 @@ color_atoh(const char *col) return (Color)strtol(col + shift, NULL, 16); } +static inline void +swap_ptr(void **x, void **y) +{ + void *t = *x; + + *x = *y; + *y = t; +} + void *xmalloc(size_t nmemb, size_t size); void *xcalloc(size_t nmemb, size_t size); int xasprintf(char **strp, const char *fmt, ...); diff --git a/wmfs2/wmfsrc2 b/wmfs2/wmfsrc2 index 799d52b..24f035d 100644 --- a/wmfs2/wmfsrc2 +++ b/wmfs2/wmfsrc2 @@ -104,7 +104,7 @@ [keys] - [key] mod = {"Control"} key = "Return" func = "spawn" cmd = "xterm" [/key] + [key] mod = {"Super"} key = "Return" func = "spawn" cmd = "xterm" [/key] [key] mod = {"Control","Alt"} key = "q" func = "quit" [/key] [key] mod = {"Super"} key = "1" func = "tag_set" cmd = "1" [/key] [key] mod = {"Super"} key = "2" func = "tag_set" cmd = "2" [/key] @@ -113,6 +113,24 @@ [key] mod = {"Super"} key = "a" func = "tag_prev" [/key] [key] mod = {"Super"} key = "z" func = "tag" cmd = "tag2" [/key] + [key] mod = {"Super"} key = "q" func = "client_close" [/key] + + # Focus next / prev client + [key] mod = { "Alt" } key = "Tab" func = "client_focus_next" [/key] + [key] mod = { "Alt", "Shift" } key = "Tab" func = "client_focus_prev" [/key] + + # Focus next client with direction + [key] mod = {"Alt"} key = "h" func = "client_focus_left" [/key] + [key] mod = {"Alt"} key = "l" func = "client_focus_right" [/key] + [key] mod = {"Alt"} key = "k" func = "client_focus_top" [/key] + [key] mod = {"Alt"} key = "j" func = "client_focus_bottom" [/key] + + # swap next client with direction: + [key] mod = {"Control", "Shift"} key = "h" func = "client_swap_left" [/key] + [key] mod = {"Control", "Shift"} key = "l" func = "client_swap_right" [/key] + [key] mod = {"Control", "Shift"} key = "k" func = "client_swap_top" [/key] + [key] mod = {"Control", "Shift"} key = "j" func = "client_swap_bottom" [/key] + # Resize selected tiled client with direction [key] mod = {"Super"} key = "h" func = "client_resize_left" cmd = "20" [/key] [key] mod = {"Super"} key = "l" func = "client_resize_left" cmd = "-20" [/key]