From 83d56269f028d42b58aa944ff91512eb2e1468ce Mon Sep 17 00:00:00 2001 From: Martin Duquesnoy Date: Thu, 2 Jun 2011 17:41:53 +0200 Subject: [PATCH] Cfactor/Client: Use macro to generate redundant uicb functions --- src/cfactor.c | 62 +++---------- src/client.c | 237 +++++++++++++++++++++++++++----------------------- src/config.c | 28 +++--- src/wmfs.h | 33 ++++--- 4 files changed, 178 insertions(+), 182 deletions(-) diff --git a/src/cfactor.c b/src/cfactor.c index 3c9a845..d0e8de5 100644 --- a/src/cfactor.c +++ b/src/cfactor.c @@ -32,6 +32,20 @@ #include "wmfs.h" +#define CLIENT_RESIZE_DIR(d) \ +void \ +uicb_client_resize_##d(uicb_t cmd) \ +{ \ + CHECK(sel); \ + cfactor_set(sel, d, atoi(cmd)); \ +} + +/* uicb_client_resize_dir() */ +CLIENT_RESIZE_DIR(Right); +CLIENT_RESIZE_DIR(Left); +CLIENT_RESIZE_DIR(Top); +CLIENT_RESIZE_DIR(Bottom); + /** Clean client tile factors *\param c Client pointer */ @@ -302,51 +316,3 @@ cfactor_multi_set(Client *c, int fac[4]) return; } -void -uicb_client_resize_right(uicb_t cmd) -{ - int n = atoi(cmd); - - CHECK(sel); - - cfactor_set(sel, Right, n); - - return; -} - -void -uicb_client_resize_left(uicb_t cmd) -{ - int n = atoi(cmd); - - CHECK(sel); - - cfactor_set(sel, Left, n); - - return; -} - -void -uicb_client_resize_top(uicb_t cmd) -{ - int n = atoi(cmd); - - CHECK(sel); - - cfactor_set(sel, Top, n); - - return; -} - -void -uicb_client_resize_bottom(uicb_t cmd) -{ - int n = atoi(cmd); - - CHECK(sel); - - cfactor_set(sel, Bottom, n); - - return; -} - diff --git a/src/client.c b/src/client.c index db9c556..6fb89ff 100644 --- a/src/client.c +++ b/src/client.c @@ -88,7 +88,7 @@ client_detach(Client *c) /** Get the next client *\return The next client or NULL */ -Client* +static Client* client_get_next(void) { Client *c = NULL; @@ -132,34 +132,46 @@ client_get_prev(void) } /** Get client left/right/top/bottom of selected client - *\param bc Base client *\param pos Position (Left/Right/Top/Bottom *\return Client found */ -Client* -client_get_next_with_direction(Client *bc, Position pos) +static Client* +client_get_next_with_direction(Position pos) { - Client *c; - int x, y; - char scanfac[4][2] = - { - { 1, 0 }, { -1, 0 }, /* Right, Left */ - { 0, -1 }, { 0, 1 } /* Top, Bottom */ - }; + Client *c = NULL; + Client *ret = NULL; - if(!bc) + if(!sel || ishide(sel, selscreen)) return NULL; - /* Start place of pointer for faster scanning */ - x = bc->frame_geo.x + ((pos == Right) ? bc->frame_geo.width : 0); - y = bc->frame_geo.y + ((pos == Bottom) ? bc->frame_geo.height : 0); - y += ((LDIR(pos)) ? bc->frame_geo.height / 2 : 0); - x += ((pos > Left) ? bc->frame_geo.width / 2 : 0); + 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; + } - /* Scan in right direction to next(p) physical client */ - for(; (c = client_gb_pos(bc, x, y)) == bc; x += scanfac[pos][0], y += scanfac[pos][1]); - - return c; + return ret; } /** Switch to the previous client @@ -243,7 +255,7 @@ uicb_client_focus_right(uicb_t cmd) Client *c; (void)cmd; - if((c = client_get_next_with_direction(sel, Right))) + if((c = client_get_next_with_direction(Right))) { client_focus(c); client_raise(c); @@ -262,7 +274,7 @@ uicb_client_focus_left(uicb_t cmd) Client *c; (void)cmd; - if((c = client_get_next_with_direction(sel, Left))) + if((c = client_get_next_with_direction(Left))) { client_focus(c); client_raise(c); @@ -280,7 +292,7 @@ uicb_client_focus_top(uicb_t cmd) Client *c; (void)cmd; - if((c = client_get_next_with_direction(sel, Top))) + if((c = client_get_next_with_direction(Top))) { client_focus(c); client_raise(c); @@ -298,7 +310,7 @@ uicb_client_focus_bottom(uicb_t cmd) Client *c; (void)cmd; - if((c = client_get_next_with_direction(sel, Bottom))) + if((c = client_get_next_with_direction(Bottom))) { client_focus(c); client_raise(c); @@ -328,7 +340,7 @@ client_above(Client *c) geo.y = spgeo[c->screen].y + (spgeo[c->screen].height / 2) - (geo.height / 2); geo.x = spgeo[c->screen].x + (spgeo[c->screen].width / 2)- (geo.width / 2); - client_moveresize(c, geo, (tags[c->screen][c->tag].flags & ResizeHintFlag)); + client_moveresize(c, geo, tags[c->screen][c->tag].resizehint); client_raise(c); tags[c->screen][c->tag].layout.func(c->screen); @@ -385,8 +397,7 @@ client_focus(Client *c) client_raise(c); } - if((tags[sel->screen][sel->tag].flags & AboveFCFlag) - && !conf.focus_fmouse) + if(tags[sel->screen][sel->tag].abovefc && !conf.focus_fmouse) client_above(sel); if(c->flags & UrgentFlag) @@ -414,14 +425,17 @@ client_focus(Client *c) void client_urgent(Client *c, Bool u) { - FLAGAPPLY(c->flags, u, UrgentFlag); - FLAGAPPLY(tags[c->screen][c->tag].flags, u, TagUrgentFlag); + if(u) + c->flags |= UrgentFlag; + else + c->flags &= ~UrgentFlag; + tags[c->screen][c->tag].urgent = u; infobar_draw_taglist(c->screen); } /* The following functions have the same point : - * find a client member with a Window or values {{{ + * find a client member with a Window {{{ */ /* Get Client with a window */ @@ -504,29 +518,6 @@ 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* client_gb_pos(Client *c, int x, int y) - { - Client *cc; - - if(x < 0 || x > spgeo[c->screen].x + spgeo[c->screen].width - || y < 0 || y > spgeo[c->screen].y + spgeo[c->screen].height) - return NULL; - - for(cc = clients; cc; cc = cc->next) - if(cc != c && cc->screen == c->screen && cc->tag == c->tag - && (cc->flags & TileFlag)) - if(cc->frame_geo.x < x && cc->frame_geo.x + cc->frame_geo.width > x - && cc->frame_geo.y < y && cc->frame_geo.y + cc->frame_geo.height > y) - return cc; - - return c; - } - /* }}} */ /** Get a client name @@ -680,7 +671,7 @@ static void client_set_rules(Client *c) { XClassHint xch; - int i, f; + int i, j, k, f; Atom rf; ulong n, il; uchar *data = NULL; @@ -707,14 +698,51 @@ client_set_rules(Client *c) XFree(data); } + /* Following features is *DEPRECATED*, will be removed in some revision. {{{ */ + + /* Auto free */ + if(conf.client.autofree && ((xch.res_name && strstr(conf.client.autofree, xch.res_name)) + || (xch.res_class && strstr(conf.client.autofree, xch.res_class)))) + c->flags |= FreeFlag; + + /* Auto maximize */ + if(conf.client.automax && ((xch.res_name && strstr(conf.client.automax, xch.res_name)) + || (xch.res_class && strstr(conf.client.automax, xch.res_class)))) + { + client_maximize(c); + c->flags |= MaxFlag; + } + + /* Wanted tag */ + for(i = 0; i < screen_count(); ++i) + for(j = 1; j < conf.ntag[i] + 1; ++j) + if(tags[i][j].clients) + for(k = 0; k < tags[i][j].nclients; ++k) + if((xch.res_name && strstr(xch.res_name, tags[i][j].clients[k])) + || (xch.res_class && strstr(xch.res_class, tags[i][j].clients[k]))) + { + c->screen = i; + c->tag = j; + + if(c->tag != (uint)seltag[selscreen]) + tags[c->screen][c->tag].request_update = True; + else + tags[c->screen][c->tag].layout.func(c->screen); + + /* Deprecated but still in use */ + applied_tag_rule = True; + applied_screen_rule = True; + } + + /* }}} */ + /* Apply Rule if class || instance || role match */ for(i = 0; i < conf.nrule; ++i) { if((xch.res_class && conf.rule[i].class && !strcmp(xch.res_class, conf.rule[i].class)) || (xch.res_name && conf.rule[i].instance && !strcmp(xch.res_name, conf.rule[i].instance))) { - if((strlen(wwrole) && conf.rule[i].role && !strcmp(wwrole, conf.rule[i].role)) - || (!strlen(wwrole) || !conf.rule[i].role)) + if((strlen(wwrole) && conf.rule[i].role && !strcmp(wwrole, conf.rule[i].role)) || (!strlen(wwrole) || !conf.rule[i].role)) { if(conf.rule[i].screen != -1) c->screen = conf.rule[i].screen; @@ -733,13 +761,13 @@ client_set_rules(Client *c) if(conf.rule[i].max) { - c->flags |= MaxFlag; client_maximize(c); + c->flags |= MaxFlag; } if(c->tag != (uint)seltag[selscreen]) { - tags[c->screen][c->tag].flags |= RequestUpdateFlag; + tags[c->screen][c->tag].request_update = True; client_focus(NULL); } @@ -758,7 +786,7 @@ client_set_rules(Client *c) c->tag = conf.client.default_open_tag; client_focus_next(c); - tags[c->screen][c->tag].flags |= RequestUpdateFlag; + tags[c->screen][c->tag].request_update = True; } if(!applied_screen_rule && conf.client.default_open_screen > -1 @@ -767,7 +795,7 @@ client_set_rules(Client *c) c->screen = conf.client.default_open_screen; client_focus_next(c); - tags[c->screen][c->tag].flags |= RequestUpdateFlag; + tags[c->screen][c->tag].request_update = True; } return; @@ -835,10 +863,11 @@ client_manage(Window w, XWindowAttributes *wa, Bool ar) c->ogeo.y = c->geo.y = my; c->ogeo.width = c->geo.width = wa->width; c->ogeo.height = c->geo.height = wa->height; - c->free_geo = c->pgeo = c->wrgeo = c->split_geo = c->geo; + c->free_geo = c->geo; c->tag = seltag[c->screen]; c->focusontag = -1; - cfactor_clean(c); + + c->layer = (sel && sel->layer > 0) ? sel->layer : 1; at.event_mask = PropertyChangeMask; @@ -850,7 +879,7 @@ client_manage(Window w, XWindowAttributes *wa, Bool ar) XSetWindowBorderWidth(dpy, c->win, 0); mouse_grabbuttons(c, False); - /* Transient for tag setting */ + /* Transient */ if((rettrans = XGetTransientForHint(dpy, w, &trans) == Success)) for(t = clients; t && t->win != trans; t = t->next); @@ -859,27 +888,28 @@ client_manage(Window w, XWindowAttributes *wa, Bool ar) c->tag = t->tag; c->screen = t->screen; } + if(!(c->flags & FreeFlag) && (rettrans == Success || (c->flags & HintFlag))) c->flags |= FreeFlag; + free(t); client_attach(c); client_set_rules(c); client_get_name(c); - tags[c->screen][c->tag].flags |= CleanFactFlag; - if(c->tag == (uint)seltag[selscreen]) { client_raise(c); - client_map(c); setwinstate(c->win, NormalState); } else client_hide(c); - client_update_attributes(c); ewmh_get_client_list(); + client_update_attributes(c); + if(c->tag == (uint)seltag[selscreen]) + client_map(c); ewmh_manage_window_type(c); if(ar) @@ -900,6 +930,7 @@ client_manage(Window w, XWindowAttributes *wa, Bool ar) c->geo.y + c->geo.height / 2); } + return c; } @@ -961,57 +992,40 @@ client_geo_hints(XRectangle *geo, Client *c) void client_moveresize(Client *c, XRectangle geo, Bool r) { - int os, e; - int rhx = 0; + int os; if(!c) return; os = c->screen; - /* Apply padding and cfactor */ - if(c->flags & TileFlag) - { - geo = cfactor_geo(c->pgeo, c->tilefact, &e); - - if(conf.client.padding && (c->flags & FLayFlag)) - { - geo.x += conf.client.padding; - geo.y += conf.client.padding; - geo.width -= conf.client.padding * 2; - geo.height -= conf.client.padding * 2; - - c->flags &= ~FLayFlag; - } - } - - /* Set geo without resizehint applied */ - c->wrgeo = geo; - - /* Apply geometry hints */ if(r) - { client_geo_hints(&geo, c); - /* To balance position of window in frame */ - rhx = ((c->wrgeo.width) - geo.width) / 2; - } + c->flags &= ~MaxFlag; + + if(conf.client.padding && c->flags & TileFlag && c->flags & FLayFlag) + { + geo.x += conf.client.padding; + geo.y += conf.client.padding; + geo.width -= conf.client.padding * 2; + geo.height -= conf.client.padding * 2; + + c->flags &= ~FLayFlag; + } c->geo = geo; - /* Sett free_geo */ - if(c->flags & FreeFlag || !(c->flags & (TileFlag | LMaxFlag)) - || conf.keep_layout_geo) + if(c->flags & FreeFlag || !(c->flags & (TileFlag | LMaxFlag)) || conf.keep_layout_geo) c->free_geo = c->geo; - /* Check to set new screen if needed */ if((c->screen = screen_get_with_geo(c->geo.x, c->geo.y)) != os && c->tag != MAXTAG + 1) c->tag = seltag[c->screen]; - frame_moveresize(c, c->wrgeo); + frame_moveresize(c, c->geo); - XMoveResizeWindow(dpy, c->win, BORDH + rhx, TBARH, c->geo.width, c->geo.height); + XMoveResizeWindow(dpy, c->win, BORDH, TBARH, c->geo.width, c->geo.height); client_update_attributes(c); client_configure(c); @@ -1028,15 +1042,17 @@ client_maximize(Client *c) if(!c || c->flags & FSSFlag) return; - cfactor_clean(c); c->screen = screen_get_with_geo(c->geo.x, c->geo.y); c->geo.x = sgeo[c->screen].x; - c->geo.y = sgeo[c->screen].y ; + c->geo.y = sgeo[c->screen].y; c->geo.width = sgeo[c->screen].width - BORDH * 2; c->geo.height = sgeo[c->screen].height - BORDH; - client_moveresize(c, (c->pgeo = c->geo), (tags[c->screen][c->tag].flags & ResizeHintFlag)); + client_moveresize(c, c->geo, False); + + /* Raise for maximized clients, client_raise has too much condition */ + XRaiseWindow(dpy, c->frame); return; } @@ -1152,8 +1168,8 @@ client_swap(Client *c1, Client *c2) client_size_hints(c2); /* Resize the windows */ - client_moveresize(c1, c1->geo, (tags[c1->screen][c1->tag].flags & ResizeHintFlag)); - client_moveresize(c2, c2->geo, (tags[c2->screen][c2->tag].flags & ResizeHintFlag)); + client_moveresize(c1, c1->geo, False); + client_moveresize(c2, c2->geo, False); /* Get the new client name */ client_get_name(c1); @@ -1277,13 +1293,11 @@ client_unmanage(Client *c) XUngrabServer(dpy); ewmh_get_client_list(); - if(c->flags & TileFlag) - tags[c->screen][c->tag].flags |= CleanFactFlag; if(c->tag == MAXTAG + 1) { for(i = 0; i < conf.ntag[c->screen]; i++) - tags[c->screen][i].flags |= RequestUpdateFlag; + tags[c->screen][i].request_update = True; tags[c->screen][seltag[c->screen]].layout.func(c->screen); } else @@ -1305,11 +1319,15 @@ client_unmanage(Client *c) tags[c->screen][c->tag].layout.func(c->screen); else { - tags[c->screen][c->tag].flags |= RequestUpdateFlag; + tags[c->screen][c->tag].request_update = True; infobar_draw(c->screen); } } + + + /*XFree(c->title);*/ + client_focus_next(c); free(c); @@ -1641,4 +1659,3 @@ uicb_client_set_master(uicb_t cmd) } return; } - diff --git a/src/config.c b/src/config.c index 2dd5003..419fd95 100644 --- a/src/config.c +++ b/src/config.c @@ -36,25 +36,29 @@ const func_name_list_t func_list[] = { {"spawn", uicb_spawn }, {"client_kill", uicb_client_kill }, - {"client_prev", uicb_client_prev }, - {"client_next", uicb_client_next }, - {"client_swap_next", uicb_client_swap_next }, - {"client_swap_prev", uicb_client_swap_prev }, + {"client_prev", uicb_client_focus_prev }, + {"client_next", uicb_client_focus_next }, + {"client_swap_next", uicb_client_swapsel_next }, + {"client_swap_prev", uicb_client_swapsel_prev }, + {"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_screen_next", uicb_client_screen_next }, {"client_screen_prev", uicb_client_screen_prev }, {"client_screen_set", uicb_client_screen_set }, - {"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_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 }, {"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 }, + {"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/wmfs.h b/src/wmfs.h index aaad571..81ac378 100644 --- a/src/wmfs.h +++ b/src/wmfs.h @@ -162,10 +162,12 @@ Bool cfactor_check_2pc(XRectangle g1, XRectangle g2, Position p); Bool cfactor_parentrow(XRectangle cg, XRectangle ccg, Position p); void cfactor_set(Client *c, Position p, int fac); void cfactor_multi_set(Client *c, int fac[4]); -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); +/* Generated with macro {{{ */ +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); +/* }}} */ /* client.c */ void client_attach(Client *c); @@ -173,6 +175,7 @@ void client_configure(Client *c); void client_detach(Client *c); void client_focus(Client *c); Client *client_get_next(void); +Client *client_get_prev(void); /* client_gb_*() {{{ */ Client* client_gb_win(Window w); Client* client_gb_frame(Window w); @@ -201,14 +204,20 @@ void client_update_attributes(Client *c); void client_urgent(Client *c, Bool u); Client* client_get_next_with_direction(Client *bc, Position pos); void uicb_client_raise(uicb_t); -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); +/* Generated with macro {{{ */ +void uicb_client_focus_next(uicb_t); +void uicb_client_focus_prev(uicb_t); +void uicb_client_swapsel_next(uicb_t); +void uicb_client_swapsel_prev(uicb_t); +void uicb_client_swapsel_Right(uicb_t); +void uicb_client_swapsel_Left(uicb_t); +void uicb_client_swapsel_Top(uicb_t); +void uicb_client_swapsel_Bottom(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);