Add client user functions: swap/focus with direction and list (next/prev)
This commit is contained in:
@@ -15,11 +15,27 @@
|
|||||||
|
|
||||||
#define CLIENT_MOUSE_MOD Mod1Mask
|
#define CLIENT_MOUSE_MOD Mod1Mask
|
||||||
|
|
||||||
#define CLIENT_RESIZE_DIR(d) \
|
#define CLIENT_RESIZE_DIR(D) \
|
||||||
void uicb_client_resize_##d(Uicb cmd) \
|
void uicb_client_resize_##D(Uicb cmd) \
|
||||||
{ \
|
{ \
|
||||||
if(W->client) \
|
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() */
|
/* uicb_client_resize_dir() */
|
||||||
@@ -28,6 +44,27 @@ CLIENT_RESIZE_DIR(Left)
|
|||||||
CLIENT_RESIZE_DIR(Top)
|
CLIENT_RESIZE_DIR(Top)
|
||||||
CLIENT_RESIZE_DIR(Bottom)
|
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
|
/** Send a ConfigureRequest event to the struct client
|
||||||
* \param c struct client pointer
|
* \param c struct client pointer
|
||||||
*/
|
*/
|
||||||
@@ -52,6 +89,29 @@ client_configure(struct client *c)
|
|||||||
XSync(W->dpy, False);
|
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*
|
struct client*
|
||||||
client_gb_win(Window w)
|
client_gb_win(Window w)
|
||||||
{
|
{
|
||||||
@@ -111,6 +171,27 @@ client_next_with_pos(struct client *bc, Position p)
|
|||||||
return c;
|
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
|
static void
|
||||||
client_grabbuttons(struct client *c, bool focused)
|
client_grabbuttons(struct client *c, bool focused)
|
||||||
{
|
{
|
||||||
@@ -143,15 +224,15 @@ client_grabbuttons(struct client *c, bool focused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
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 */
|
/* Selected client's border */
|
||||||
if(W->client)
|
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;
|
c->tag->sel = c;
|
||||||
|
|
||||||
client_draw_bord();
|
client_draw_bord(c);
|
||||||
|
|
||||||
client_grabbuttons(c, true);
|
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;
|
int bord = THEME_DEFAULT->client_border_width;
|
||||||
|
|
||||||
c->geo = c->wgeo = g;
|
c->geo = g;
|
||||||
|
|
||||||
/* Window geo */
|
/* Window geo */
|
||||||
c->wgeo.x += bord;
|
c->wgeo.x = g.x + bord;
|
||||||
c->wgeo.y += bord ;
|
c->wgeo.y = g.y + bord ;
|
||||||
c->wgeo.w -= (bord << 1);
|
c->wgeo.w = g.w - (bord << 1);
|
||||||
c->wgeo.h -= (bord << 1);
|
c->wgeo.h = g.h - (bord << 1);
|
||||||
|
|
||||||
XMoveResizeWindow(W->dpy, c->win,
|
XMoveResizeWindow(W->dpy, c->win,
|
||||||
c->wgeo.x, c->wgeo.y,
|
c->wgeo.x, c->wgeo.y,
|
||||||
c->wgeo.w, c->wgeo.h);
|
c->wgeo.w, c->wgeo.h);
|
||||||
|
|
||||||
client_draw_bord();
|
client_draw_bord(c);
|
||||||
|
client_configure(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -10,9 +10,13 @@
|
|||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
|
|
||||||
void client_configure(struct client *c);
|
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_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);
|
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_focus(struct client *c);
|
||||||
void client_get_name(struct client *c);
|
void client_get_name(struct client *c);
|
||||||
void client_close(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_fac_resize(struct client *c, Position p, int fac);
|
||||||
void client_remove(struct client *c);
|
void client_remove(struct client *c);
|
||||||
void client_free(void);
|
void client_free(void);
|
||||||
|
|
||||||
|
/* Generated */
|
||||||
void uicb_client_resize_Right(Uicb);
|
void uicb_client_resize_Right(Uicb);
|
||||||
void uicb_client_resize_Left(Uicb);
|
void uicb_client_resize_Left(Uicb);
|
||||||
void uicb_client_resize_Top(Uicb);
|
void uicb_client_resize_Top(Uicb);
|
||||||
void uicb_client_resize_Bottom(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
|
static inline bool
|
||||||
client_fac_geo(struct client *c, Position p, int fac)
|
client_fac_geo(struct client *c, Position p, int fac)
|
||||||
|
|||||||
@@ -36,7 +36,18 @@ static const struct { char *name; void (*func)(Uicb cmd); } uicb_list[] =
|
|||||||
{ "client_resize_left", uicb_client_resize_Left },
|
{ "client_resize_left", uicb_client_resize_Left },
|
||||||
{ "client_resize_top", uicb_client_resize_Top },
|
{ "client_resize_top", uicb_client_resize_Top },
|
||||||
{ "client_resize_bottom", uicb_client_resize_Bottom },
|
{ "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 }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ event_buttonpress(XEvent *e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
static void
|
static void
|
||||||
event_enternotify(XEvent *e)
|
event_enternotify(XEvent *e)
|
||||||
{
|
{
|
||||||
@@ -48,12 +49,13 @@ event_enternotify(XEvent *e)
|
|||||||
if((c = client_gb_win(ev->window)))
|
if((c = client_gb_win(ev->window)))
|
||||||
client_focus(c);
|
client_focus(c);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
event_clientmessageevent(XEvent *e)
|
event_clientmessageevent(XEvent *e)
|
||||||
{
|
{
|
||||||
/* XclientMessageEvent *ev = &e->xclient;
|
/* XClientMessageEvent *ev = &e->xclient;
|
||||||
client *c;*/
|
client *c;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -184,15 +186,12 @@ event_unmapnotify(XEvent *e)
|
|||||||
static void
|
static void
|
||||||
event_motionnotify(XEvent *e)
|
event_motionnotify(XEvent *e)
|
||||||
{
|
{
|
||||||
/*
|
XMotionEvent *ev = &e->xmotion;
|
||||||
XMotionEvent *ev = &e->xmotion;
|
struct client *c;
|
||||||
client *c;
|
|
||||||
|
|
||||||
|
/* Option follow mouvement */
|
||||||
* Option follow mouvement
|
if((c = client_gb_win(ev->subwindow)) && c != c->tag->sel)
|
||||||
if((c = client_gb_win(ev->subwindow)) && c != c->tag->sel)
|
client_focus(c);
|
||||||
client_focus(c);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -243,7 +242,7 @@ event_init(void)
|
|||||||
event_handle[ClientMessage] = event_clientmessageevent;
|
event_handle[ClientMessage] = event_clientmessageevent;
|
||||||
event_handle[ConfigureRequest] = event_configureevent;
|
event_handle[ConfigureRequest] = event_configureevent;
|
||||||
event_handle[DestroyNotify] = event_destroynotify;
|
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[Expose] = event_expose;
|
||||||
event_handle[FocusIn] = event_focusin;
|
event_handle[FocusIn] = event_focusin;
|
||||||
event_handle[KeyPress] = event_keypress;
|
event_handle[KeyPress] = event_keypress;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
#include "infobar.h"
|
#include "infobar.h"
|
||||||
|
#include "client.h"
|
||||||
|
|
||||||
static struct screen*
|
static struct screen*
|
||||||
screen_new(struct geo *g, int id)
|
screen_new(struct geo *g, int id)
|
||||||
@@ -91,6 +92,8 @@ screen_update_sel(void)
|
|||||||
if(INAREA(x, y, s->geo))
|
if(INAREA(x, y, s->geo))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
client_focus(s->seltag->sel);
|
||||||
|
|
||||||
return (W->screen = s);
|
return (W->screen = s);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_XINERAMA */
|
#endif /* HAVE_XINERAMA */
|
||||||
|
|||||||
@@ -44,6 +44,15 @@ color_atoh(const char *col)
|
|||||||
return (Color)strtol(col + shift, NULL, 16);
|
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 *xmalloc(size_t nmemb, size_t size);
|
||||||
void *xcalloc(size_t nmemb, size_t size);
|
void *xcalloc(size_t nmemb, size_t size);
|
||||||
int xasprintf(char **strp, const char *fmt, ...);
|
int xasprintf(char **strp, const char *fmt, ...);
|
||||||
|
|||||||
@@ -104,7 +104,7 @@
|
|||||||
|
|
||||||
[keys]
|
[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 = {"Control","Alt"} key = "q" func = "quit" [/key]
|
||||||
[key] mod = {"Super"} key = "1" func = "tag_set" cmd = "1" [/key]
|
[key] mod = {"Super"} key = "1" func = "tag_set" cmd = "1" [/key]
|
||||||
[key] mod = {"Super"} key = "2" func = "tag_set" cmd = "2" [/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 = "a" func = "tag_prev" [/key]
|
||||||
[key] mod = {"Super"} key = "z" func = "tag" cmd = "tag2" [/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
|
# Resize selected tiled client with direction
|
||||||
[key] mod = {"Super"} key = "h" func = "client_resize_left" cmd = "20" [/key]
|
[key] mod = {"Super"} key = "h" func = "client_resize_left" cmd = "20" [/key]
|
||||||
[key] mod = {"Super"} key = "l" func = "client_resize_left" cmd = "-20" [/key]
|
[key] mod = {"Super"} key = "l" func = "client_resize_left" cmd = "-20" [/key]
|
||||||
|
|||||||
Reference in New Issue
Block a user