diff --git a/src/client.c b/src/client.c index 6fb89ff..8b7a650 100644 --- a/src/client.c +++ b/src/client.c @@ -435,7 +435,7 @@ client_urgent(Client *c, Bool u) } /* The following functions have the same point : - * find a client member with a Window {{{ + * find a client member with a Window or values {{{ */ /* Get Client with a window */ @@ -518,6 +518,35 @@ client_urgent(Client *c, Bool u) return NULL; } +/** Get a client with a position + * \param x x value + * \param y y value + * \return The client +*/ + Client* get_client_with_pos(int x, int y) + { + Client *c, *psel = sel; + Window w; + int d, dx, dy, basex, basey; + + if(x < 1 || x > sgeo[selscreen].width + || y < 1 || y > sgeo[selscreen].height) + return NULL; + + XQueryPointer(dpy, ROOT, &w, &w, &basex, &basey, &d, &d, (uint *)&d); + XWarpPointer(dpy, None, ROOT, 0, 0, 0, 0, x, y); + XQueryPointer(dpy, ROOT, &w, &w, &dx, &dy, &d, &d, (uint *)&d); + XWarpPointer(dpy, None, ROOT, 0, 0, 0, 0, basex, basey); + + if(psel) + client_focus(psel); + + if((c = client_gb_frame(w)) || (c = client_gb_win(w))) + return c; + + return NULL; + } + /* }}} */ /** Get a client name @@ -1659,3 +1688,127 @@ uicb_client_set_master(uicb_t cmd) } return; } + +/** Manual resizing of tiled clients + * \param c Client pointer + * \param p Direction of resizing + * \param fac Factor of resizing +*/ +static void +client_tile_factor_set(Client *c, Position p, int fac) +{ + Client *gc = NULL; + int x, y; + XRectangle cgeo, scgeo; + char scanfac[4][3] = + { + { 1, 0 }, { -1, 0 }, /* Right, Left */ + { 0, -1 }, { 0, 1 } /* Top, Bottom */ + }; + + if(!c || !(c->flags & TileFlag) || p > Bottom) + return; + + cgeo = c->geo; + + /* Scan in right direction to next(p) physical client */ + x = c->geo.x + ((p == Right) ? c->geo.width : 0); + y = c->geo.y + ((p == Bottom) ? c->geo.height : 0); + for(; (gc = get_client_with_pos(x, y)) == c; x += scanfac[p][0], y += scanfac[p][1]); + + if(!gc) + return; + + scgeo = gc->geo; + + /* Modify client geometry */ + switch(p) + { + default: + case Right: + scgeo.x += fac; + cgeo.width += fac; + scgeo.width -= fac; + break; + case Left: + cgeo.x -= fac; + cgeo.width += fac; + scgeo.width -= fac; + break; + case Top: + cgeo.y -= fac; + cgeo.height += fac; + scgeo.height -= fac; + break; + case Bottom: + scgeo.y += fac; + cgeo.height += fac; + scgeo.height -= fac; + break; + } + + /* Too big */ + if(scgeo.width > (1 << 15) || scgeo.height > (1 << 15) + || cgeo.width > (1 << 15) || cgeo.height > (1 << 15)) + return; + + /* Too small */ + if(scgeo.width < 1 || scgeo.height < 1 + || cgeo.width < 1 || cgeo.height < 1) + return; + + /* Magic moment */ + client_moveresize(c, cgeo, tags[c->screen][c->tag].resizehint); + client_moveresize(gc, scgeo, tags[gc->screen][gc->tag].resizehint); + + return; +} + +void +uicb_client_resize_right(uicb_t cmd) +{ + int n = atoi(cmd); + + CHECK(sel); + + client_tile_factor_set(sel, Right, n); + + return; +} + +void +uicb_client_resize_left(uicb_t cmd) +{ + int n = atoi(cmd); + + CHECK(sel); + + client_tile_factor_set(sel, Left, n); + + return; +} + +void +uicb_client_resize_top(uicb_t cmd) +{ + int n = atoi(cmd); + + CHECK(sel); + + client_tile_factor_set(sel, Top, n); + + return; +} + +void +uicb_client_resize_bottom(uicb_t cmd) +{ + int n = atoi(cmd); + + CHECK(sel); + + client_tile_factor_set(sel, Bottom, n); + + return; +} + diff --git a/src/config.c b/src/config.c index 73e320b..42ec3ce 100644 --- a/src/config.c +++ b/src/config.c @@ -51,6 +51,10 @@ const func_name_list_t func_list[] = {"client_resize", uicb_client_resize }, {"client_ignore_tag", uicb_client_ignore_tag }, {"client_set_master", uicb_client_set_master }, + {"client_resize_right", uicb_client_resize_right }, + {"client_resize_left", uicb_client_resize_left }, + {"client_resize_top", uicb_client_resize_top }, + {"client_resize_bottom", uicb_client_resize_bottom }, {"toggle_max", uicb_togglemax }, {"layout_next", uicb_layout_next }, {"layout_prev", uicb_layout_prev }, diff --git a/src/structs.h b/src/structs.h index 49e9e00..7cf496a 100644 --- a/src/structs.h +++ b/src/structs.h @@ -95,7 +95,7 @@ enum { MA_Center = 0, MA_Left = 1, MA_Right = 2 }; /* Infobar position */ enum { IB_Hide = 0, IB_Bottom = 1, IB_Top = 2 }; -typedef enum { Right, Left, Top, Bottom, Center, PositionLast } Position; +typedef enum { Right = 0, Left, Top, Bottom, Center, PositionLast } Position; /* Ewmh hints list */ enum diff --git a/src/wmfs.h b/src/wmfs.h index b0c3890..4479263 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -163,6 +163,7 @@ Client* client_gb_frame(Window w); Client* client_gb_titlebar(Window w); Client* client_gb_resize(Window w); Client* client_gb_button(Window w, int *n); +Client* get_client_with_pos(int x, int y); /* }}} */ void client_get_name(Client *c); void client_hide(Client *c); @@ -202,6 +203,10 @@ void uicb_clientlist(uicb_t cmd); Bool uicb_checkclist(uicb_t); void uicb_client_ignore_tag(uicb_t); void uicb_client_set_master(uicb_t); +void uicb_client_resize_right(uicb_t cmd); +void uicb_client_resize_left(uicb_t cmd); +void uicb_client_resize_top(uicb_t cmd); +void uicb_client_resize_bottom(uicb_t cmd); /* ewmh.c */ void ewmh_init_hints(void);