directionalfocus.c (2285B)
1 void 2 focusdir(const Arg *arg) 3 { 4 Client *s = selmon->sel, *f = NULL, *c, *next; 5 6 if (!s) 7 return; 8 9 unsigned int score = -1; 10 unsigned int client_score; 11 int isfloating = s->isfloating; 12 13 next = s->next; 14 if (!next) 15 next = s->mon->clients; 16 for (c = next; c != s; c = next) { 17 18 next = c->next; 19 if (!next) 20 next = s->mon->clients; 21 22 if (!ISVISIBLE(c) || c->isfloating != isfloating) 23 continue; 24 25 #if INFINITE_TAGS 26 if (selmon->lt[selmon->sellt]->arrange == NULL) { 27 28 int s_cx = s->x + s->w / 2; 29 int s_cy = s->y + s->h / 2; 30 int c_cx = c->x + c->w / 2; 31 int c_cy = c->y + c->h / 2; 32 33 int dx = c_cx - s_cx; /* positive = c is to the right */ 34 int dy = c_cy - s_cy; /* positive = c is below */ 35 36 int axial, lateral; 37 38 switch (arg->i) { 39 case 0: /* left */ 40 if (dx >= 0) continue; 41 axial = -dx; 42 lateral = abs(dy); 43 break; 44 case 1: /* right */ 45 if (dx <= 0) continue; 46 axial = dx; 47 lateral = abs(dy); 48 break; 49 case 2: /* up */ 50 if (dy >= 0) continue; 51 axial = -dy; 52 lateral = abs(dx); 53 break; 54 default: 55 case 3: /* down */ 56 if (dy <= 0) continue; 57 axial = dy; 58 lateral = abs(dx); 59 break; 60 } 61 62 client_score = axial + (unsigned int)((long)lateral * lateral) / (axial + 1); 63 } else 64 #endif 65 { 66 int dist; 67 int dirweight = 20; 68 switch (arg->i) { 69 case 0: 70 dist = s->x - c->x - c->w; 71 client_score = 72 dirweight * abs(dist) + 73 abs(s->y - c->y); 74 break; 75 case 1: 76 dist = c->x - s->x - s->w; 77 client_score = 78 dirweight * abs(dist) + 79 abs(c->y - s->y); 80 break; 81 case 2: 82 dist = s->y - c->y - c->h; 83 client_score = 84 dirweight * abs(dist) + 85 abs(s->x - c->x); 86 break; 87 default: 88 case 3: 89 dist = c->y - s->y - s->h; 90 client_score = 91 dirweight * abs(dist) + 92 abs(c->x - s->x); 93 break; 94 } 95 } 96 97 if (client_score < score) { 98 score = client_score; 99 f = c; 100 } 101 } 102 103 if (f && f != s) { 104 focus(f); 105 #if INFINITE_TAGS 106 centerwindow(NULL); 107 #endif 108 #if WARP_TO_CLIENT && WARP_TO_CENTER_OF_WINDOW_AFFECTED_BY_FOCUSSTACK 109 warptoclient(f); 110 #endif 111 restack(f->mon); 112 } 113 }