Add preview border for client_swap_dir

This commit is contained in:
Martin Duquesnoy 2011-10-11 03:29:22 +02:00
parent dfc277a7a3
commit 8925e99525
3 changed files with 139 additions and 29 deletions

View File

@ -32,6 +32,14 @@ void uicb_client_##A##_##D(Uicb cmd) \
client_##A(c); \
}
#define CLIENT_ACTION_IDIR(A, D) \
void uicb_client_##A##_##D(Uicb cmd) \
{ \
(void)cmd; \
if(W->client) \
client_##A(W->client, D); \
}
#define CLIENT_ACTION_LIST(A, L) \
void uicb_client_##A##_##L(Uicb cmd) \
{ \
@ -53,18 +61,18 @@ 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_swap_dir() */
CLIENT_ACTION_IDIR(swap, Right)
CLIENT_ACTION_IDIR(swap, Left)
CLIENT_ACTION_IDIR(swap, Top)
CLIENT_ACTION_IDIR(swap, Bottom)
/* uicb_client_focus_next/prev() */
CLIENT_ACTION_LIST(focus, next)
CLIENT_ACTION_LIST(focus, prev)
/* uicb_client_swapsel_next/prev() */
#define client_swapsel(c) client_swap2(W->client, c)
CLIENT_ACTION_LIST(swapsel, next)
CLIENT_ACTION_LIST(swapsel, prev)
@ -147,35 +155,138 @@ client_next_with_pos(struct client *bc, enum position p)
}
void
client_swap(struct client *c1, struct client *c2)
client_swap2(struct client *c1, struct client *c2)
{
struct tag *t;
struct geo g, foo;
/* Conflict / errors */
if(c1 == c2 || !c1 || !c2)
return;
/* are swapped geos compatible? */
if(client_winsize(c1, &c2->geo, &foo)
|| client_winsize(c2, &c1->geo, &foo))
if(client_winsize(c1, &c2->geo, &c1->wgeo)
|| client_winsize(c2, &c1->geo, &c2->wgeo))
return;
t = c1->tag;
g = c1->geo;
if(c1->screen != c2->screen)
swap_ptr((void**)&c1->screen, (void**)&c2->screen);
if(c1->tag != c2->tag)
{
t = c1->tag;
tag_client(c2->tag, c1);
tag_client(t, c2);
}
client_moveresize(c1, &c2->geo);
client_moveresize(c2, &g);
c1->tgeo = c2->geo;
c2->tgeo = c1->geo;
client_moveresize(c1, &c1->tgeo);
client_moveresize(c2, &c2->tgeo);
c1->flags |= CLIENT_IGNORE_ENTER;
c2->flags |= CLIENT_IGNORE_ENTER;
}
static inline struct client*
_swap_get(struct client *c, enum position p)
{
struct client *ret = client_next_with_pos(c, p);
if(!ret)
return c;
return ret;
}
void
client_swap(struct client *c, enum position p)
{
struct keybind *k;
struct client *c2;
bool b = true;
XEvent ev;
KeySym keysym;
GC rgc;
XGCValues xgc =
{
.function = GXinvert,
.subwindow_mode = IncludeInferiors,
.line_width = THEME_DEFAULT->client_border_width
};
c2 = _swap_get(c, p);
/* TODO
if(option_simple_manual_resize)
{
_swap(c, c2);
return;
}
*/
XGrabKeyboard(W->dpy, W->root, True, GrabModeAsync, GrabModeAsync, CurrentTime);
rgc = XCreateGC(W->dpy, c->tag->frame, GCFunction | GCSubwindowMode | GCLineWidth, &xgc);
draw_reversed_rect(c->tag->frame, rgc, c2->geo);
do
{
XMaskEvent(W->dpy, KeyPressMask, &ev);
if(ev.type == KeyPress)
{
XKeyPressedEvent *ke = &ev.xkey;
keysym = XKeycodeToKeysym(W->dpy, (KeyCode)ke->keycode, 0);
draw_reversed_rect(c->tag->frame, rgc, c2->geo);
SLIST_FOREACH(k, &W->h.keybind, next)
if(k->keysym == keysym && KEYPRESS_MASK(k->mod) == KEYPRESS_MASK(ke->state)
&& k->func)
{
if(k->func == uicb_client_swap_Right)
c2 = _swap_get(c2, Right);
else if(k->func == uicb_client_swap_Left)
c2 = _swap_get(c2, Left);
else if(k->func == uicb_client_swap_Top)
c2 = _swap_get(c2, Top);
else if(k->func == uicb_client_swap_Bottom)
c2 = _swap_get(c2, Bottom);
else
{
k->func(k->cmd);
keysym = XK_Escape;
}
}
draw_reversed_rect(c->tag->frame, rgc, c2->geo);
/* Gtfo of this loop */
if(keysym == XK_Return)
break;
else if(keysym == XK_Escape)
{
b = false;
break;
}
XSync(W->dpy, False);
}
XNextEvent(W->dpy, &ev);
} while(ev.type != KeyPress);
draw_reversed_rect(c->tag->frame, rgc, c2->geo);
if(b)
client_swap2(c, c2);
XFreeGC(W->dpy, rgc);
XUngrabKeyboard(W->dpy, CurrentTime);
}
static void
client_grabbuttons(struct client *c, bool focused)
{
@ -202,7 +313,6 @@ client_grabbuttons(struct client *c, bool focused)
XGrabButton(W->dpy, AnyButton, AnyModifier, c->win, False,
ButtonMask, GrabModeAsync, GrabModeSync, None, None);
}
static inline void
@ -614,7 +724,7 @@ client_fac_resize(struct client *c, enum position p, int fac)
/* TODO
if(option_simple_manual_resize)
returnl
return;
*/
XGrabKeyboard(W->dpy, W->root, True, GrabModeAsync, GrabModeAsync, CurrentTime);
@ -666,7 +776,6 @@ client_fac_resize(struct client *c, enum position p, int fac)
XSync(W->dpy, False);
}
XNextEvent(W->dpy, &ev);
} while(ev.type != KeyPress);

View File

@ -13,7 +13,8 @@ inline void client_configure(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_next_with_pos(struct client *bc, enum position p);
void client_swap(struct client *c1, struct client *c2);
void client_swap2(struct client *c1, struct client *c2);
void client_swap(struct client *c, enum position p);
void client_focus(struct client *c);
void client_get_name(struct client *c);
void client_close(struct client *c);
@ -36,10 +37,10 @@ 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_swap_Right(Uicb);
void uicb_client_swap_Left(Uicb);
void uicb_client_swap_Top(Uicb);
void uicb_client_swap_Bottom(Uicb);
void uicb_client_focus_next(Uicb);
void uicb_client_focus_prev(Uicb);
void uicb_client_swapsel_next(Uicb);

View File

@ -46,10 +46,10 @@ static const struct { char *name; void (*func)(Uicb cmd); } uicb_list[] =
{ "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_swap_right", uicb_client_swap_Right },
{ "client_swap_left", uicb_client_swap_Left },
{ "client_swap_top", uicb_client_swap_Top },
{ "client_swap_bottom", uicb_client_swap_Bottom },
{ "client_focus_next", uicb_client_focus_next },
{ "client_focus_prev", uicb_client_focus_prev },
{ "client_swap_next", uicb_client_swapsel_next },