changeset: 2396:49001679f1bc
tag: tip
user: Kris Maglione <jg_AT_suckless.org>
date: Sun Oct 19 18:46:02 2008 -0400
files: cmd/menu/menu.c cmd/wmii/area.c cmd/wmii/column.c cmd/wmii/fns.h cmd/wmii/message.c cmd/wmii/screen.c cmd/wmii/view.c cmd/wmii/x11.c include/x11.h
description:
Beginnings of better ordinal selections with Xinerama
diff -r e7626a2b5aa0 -r 49001679f1bc cmd/menu/menu.c
--- a/cmd/menu/menu.c Sun Oct 19 12:32:46 2008 -0400
+++ b/cmd/menu/menu.c Sun Oct 19 18:46:02 2008 -0400
@@ -251,6 +251,14 @@
case XK_M:
menu_cmd(ACCEPT, e->state&ShiftMask);
return;
+ case XK_a:
+ case XK_A:
+ menu_cmd(BACKWARD, LINE);
+ return;
+ case XK_e:
+ case XK_E:
+ menu_cmd(FORWARD, LINE);
+ return;
case XK_n:
case XK_N:
menu_cmd(HIST, FORWARD);
diff -r e7626a2b5aa0 -r 49001679f1bc cmd/wmii/area.c
--- a/cmd/wmii/area.c Sun Oct 19 12:32:46 2008 -0400
+++ b/cmd/wmii/area.c Sun Oct 19 18:46:02 2008 -0400
@@ -26,6 +26,27 @@
for(ap=v->areas[a->screen]; a != ap; ap=ap->next)
i++;
return i;
+}
+
+static Rectangle
+area_rect(void *v) {
+ Area *a;
+
+ a = v;
+ return a->r;
+}
+
+Area*
+area_find(View *v, Rectangle r, int dir) {
+ static Vector_ptr vec;
+ Area *a;
+ int s;
+
+ vec.n = 0;
+ foreach_column(v, s, a)
+ vector_ppush(&vec, a);
+
+ return findthing(r, dir, &vec, area_rect);
}
int
diff -r e7626a2b5aa0 -r 49001679f1bc cmd/wmii/column.c
--- a/cmd/wmii/column.c Sun Oct 19 12:32:46 2008 -0400
+++ b/cmd/wmii/column.c Sun Oct 19 18:46:02 2008 -0400
@@ -6,6 +6,8 @@
#include <math.h>
#include <strings.h>
#include "fns.h"
+
+static void column_resizeframe_h(Frame*, Rectangle);
char *modes[] = {
[Coldefault] = "default",
@@ -130,13 +132,15 @@
}
static void
-stack_info(Frame *f, Frame **firstp, int *dyp, int *nframep) {
- Frame *ft, *first;
+stack_info(Frame *f, Frame **firstp, Frame **lastp, int *dyp, int *nframep) {
+ Frame *ft, *first, *last;
int dy, nframe;
nframe = 0;
dy = 0;
first = f;
+ last = f;
+
for(ft=f; ft && ft->collapsed; ft=ft->anext)
;
if(ft && ft != f) {
@@ -151,11 +155,13 @@
for(ft=f->anext; ft && !ft->collapsed; ft=ft->anext) {
if(first == nil)
first = ft;
+ last = ft;
nframe++;
dy += Dy(ft->colr);
}
if(nframep) *nframep = nframe;
if(firstp) *firstp = first;
+ if(lastp) *lastp = last;
if(dyp) *dyp = dy;
}
@@ -174,6 +180,66 @@
return n;
}
+Frame*
+stack_find(Area *a, Frame *f, int dir) {
+ Frame *fp;
+
+ switch (dir) {
+ default:
+ die("not reached");
+ case North:
+ if(f)
+ for(f=f->aprev; f && f->collapsed; f=f->aprev)
+ ;
+ else {
+ f = nil;
+ for(fp=a->frame; fp; fp=fp->anext)
+ if(!fp->collapsed)
+ f = fp;
+ }
+ break;
+ case South:
+ if(f)
+ for(f=f->anext; f && f->collapsed; f=f->anext)
+ ;
+ else
+ for(f=a->frame; f && f->collapsed; f=f->anext)
+ ;
+ break;
+ }
+ return f;
+}
+
+/* TODO: Move elsewhere. */
+bool
+find(Area **ap, Frame **fp, int dir) {
+ Rectangle r;
+ Frame *f;
+ Area *a;
+
+ f = *fp;
+ a = *ap;
+ r = f ? f->r : a->r;
+
+ if(dir == North || dir == South) {
+ *fp = stack_find(a, f, dir);
+ if(*fp)
+ return true;
+ *ap = area_find(a->view, r, dir);
+ if(!*ap)
+ return false;
+ *fp = stack_find(*ap, *fp, dir);
+ return *fp;
+ }
+ if(dir != East && dir != West)
+ die("not reached");
+ *ap = area_find(a->view, r, dir);
+ if(!*ap)
+ return false;
+ *fp = ap[0]->sel;
+ return true;
+}
+
void
column_attach(Area *a, Frame *f) {
Frame *first;
@@ -182,7 +248,7 @@
f->colr = a->r;
if(a->sel) {
- stack_info(a->sel, &first, &dy, &nframe);
+ stack_info(a->sel, &first, nil, &dy, &nframe);
h = dy / (nframe+1);
f->colr.max.y = f->colr.min.y + h;
stack_scale(first, dy - h);
@@ -199,7 +265,7 @@
int dy;
a = f->area;
- stack_info(f, &first, &dy, nil);
+ stack_info(f, &first, nil, &dy, nil);
if(first && first == f)
first = f->anext;
column_remove(f);
@@ -235,6 +301,7 @@
}
column_insert(a, f, pos);
column_scale(a);
+ column_resizeframe_h(f, r);
}
void
diff -r e7626a2b5aa0 -r 49001679f1bc cmd/wmii/fns.h
--- a/cmd/wmii/fns.h Sun Oct 19 12:32:46 2008 -0400
+++ b/cmd/wmii/fns.h Sun Oct 19 18:46:02 2008 -0400
@@ -13,18 +13,21 @@
# pragma varargck type "r" void
#endif
+#define with(type, var) \
+ for(type *var=(void*)-1; var == (void*)-1; var=nil)
+
#define foreach_area(v, s, a) \
- Area *__anext; /* Getting ugly... */ \
+ with(Area, __anext) \
for(s=0; s <= nscreens; s++) \
for((a)=(s < nscreens ? (v)->areas[s] : v->floating), __anext=(a)->next; (a); (void)(((a)=__anext) && (__anext=(a)->next)))
#define foreach_column(v, s, a) \
- Area *__anext; /* Getting ugly... */ \
+ with(Area, __anext) \
for(s=0; s < nscreens; s++) \
for((a)=(v)->areas[s], __anext=(a)->next; (a); (void)(((a)=__anext) && (__anext=(a)->next)))
#define foreach_frame(v, s, a, f) \
- Frame *__fnext; \
+ with(Frame, __fnext) \
foreach_area(v, s, a) \
for((void)(((f)=(a)->frame) && (__fnext=(f)->anext)); (f); (void)(((f)=__fnext) && (__fnext=(f)->anext)))
@@ -37,6 +40,7 @@
Area* area_create(View*, Area *pos, int scrn, uint w);
void area_destroy(Area*);
void area_detach(Frame*);
+Area* area_find(View*, Rectangle, int);
void area_focus(Area*);
int area_idx(Area*);
void area_moveto(Area*, Frame*);
@@ -105,7 +109,9 @@
void div_draw(Divide*);
void div_set(Divide*, int x);
void div_update_all(void);
+bool find(Area**, Frame**, int);
int stack_count(Frame*, int*);
+Frame* stack_find(Area*, Frame*, int);
/* event.c */
void check_x_event(IxpConn*);
@@ -241,6 +247,7 @@
void root_init(void);
/* screen.c */
+void* findthing(Rectangle, int, Vector_ptr*, Rectangle(*)(void*));
int ownerscreen(Rectangle);
/* rule.c */
diff -r e7626a2b5aa0 -r 49001679f1bc cmd/wmii/message.c
--- a/cmd/wmii/message.c Sun Oct 19 12:32:46 2008 -0400
+++ b/cmd/wmii/message.c Sun Oct 19 18:46:02 2008 -0400
@@ -7,8 +7,15 @@
static char* msg_grow(View*, IxpMsg*);
static char* msg_nudge(View*, IxpMsg*);
-static char* msg_selectframe(Frame*, IxpMsg*, int);
+static char* msg_selectframe(Area*, IxpMsg*, int);
static char* msg_sendframe(Frame*, int, bool);
+
+#define DIR(s) (\
+ s == LUP ? North : \
+ s == LDOWN ? South : \
+ s == LLEFT ? West : \
+ s == LRIGHT ? East : \
+ (abort(), 0))
static char
Ebadcmd[] = "bad command",
@@ -359,6 +366,7 @@
return client_viewframe(c, v);
}
+ /* XXX: Multihead */
a = strarea(v, scrn, s);
if(a == nil) {
fprint(2, "a == nil\n");
@@ -601,6 +609,7 @@
switch(getsym(s)) {
case LCOLMODE:
s = msg_getword(m);
+ /* XXX: Multihead */
a = strarea(v, screen->idx, s);
if(a == nil) /* || a->floating) */
return Ebadvalue;
@@ -845,29 +854,17 @@
else
ap = v->firstarea;
break;
+ case LLEFT:
+ case LRIGHT:
case LUP:
case LDOWN:
case LCLIENT:
- return msg_selectframe(a->sel, m, sym);
- case LLEFT:
- /* XXX: Multihead. */
- if(a->floating)
- return Ebadvalue;
- for(ap=v->firstarea; ap->next; ap=ap->next)
- if(ap->next == a) break;
- break;
- case LRIGHT:
- /* XXX: Multihead. */
- if(a->floating)
- return Ebadvalue;
- ap = a->next;
- if(ap == nil)
- ap = v->firstarea;
- break;
+ return msg_selectframe(a, m, sym);
case LTILDE:
ap = v->floating;
break;
default:
+ /* XXX: Multihead */
ap = strarea(v, a->screen, s);
if(!ap || ap->floating)
return Ebadvalue;
@@ -888,17 +885,15 @@
}
static char*
-msg_selectframe(Frame *f, IxpMsg *m, int sym) {
- Frame *fp;
+msg_selectframe(Area *a, IxpMsg *m, int sym) {
Client *c;
- Area *a;
+ Frame *f, *fp;
char *s;
bool stack;
ulong i, dy;
- if(!f)
- return Ebadvalue;
- a = f->area;
+ f = a->sel;
+ fp = f;
stack = false;
if(sym == LUP || sym == LDOWN) {
@@ -910,65 +905,38 @@
return Ebadvalue;
}
- SET(fp);
- switch(sym) {
- case LUP:
- /* XXX: Stack. */
- if(stack) {
- for(; f->aprev && f->aprev->collapsed; f=f->aprev)
- ;
- for(fp=a->frame; fp->anext; fp=fp->anext)
- if(fp->anext == f) break;
- for(; fp->aprev && fp->collapsed; fp=fp->aprev)
- ;
- }else
- for(fp=a->frame; fp->anext; fp=fp->anext)
- if(fp->anext == f) break;
- break;
- case LDOWN:
- /* XXX: Stack. */
- if(stack) {
- for(fp=f->anext; fp && fp->collapsed; fp=fp->anext)
- ;
- if(fp == nil)
- for(fp=a->frame; fp->collapsed; fp=fp->anext)
- ;
- }else {
- fp = f->anext;
- if(fp == nil)
- fp = a->frame;
- }
- break;
- case LCLIENT:
+ if(sym == LCLIENT) {
s = msg_getword(m);
if(s == nil || !getulong(s, &i))
return "usage: select client <client>";
c = win2client(i);
if(c == nil)
return "unknown client";
- fp = client_viewframe(c, f->view);
- break;
- default:
- die("can't get here");
+ f = client_viewframe(c, f->view);
+ if(!f)
+ return Ebadvalue;
+ }
+ else {
+ if(!find(&a, &f, DIR(sym)))
+ return Ebadvalue;
}
- if(fp == nil)
- return "invalid selection";
- if(fp == f)
+ area_focus(a);
+
+ if(!f)
return nil;
+
/* XXX */
- if(fp->collapsed && !f->area->floating && f->area->mode == Coldefault) {
+ if(a == fp->area && f->collapsed && !f->area->floating && f->area->mode == Coldefault) {
dy = Dy(f->colr);
f->colr.max.y = f->colr.min.y + Dy(fp->colr);
fp->colr.max.y = fp->colr.min.y + dy;
column_arrange(a, false);
}
- if(!f->area->floating)
- frame_draw_all();
- frame_focus(fp);
- frame_restack(fp, nil);
- if(fp->view == selview)
+ frame_focus(f);
+ frame_restack(f, nil);
+ if(f->view == selview)
view_restack(fp->view);
return nil;
}
diff -r e7626a2b5aa0 -r 49001679f1bc cmd/wmii/screen.c
--- a/cmd/wmii/screen.c Sun Oct 19 12:32:46 2008 -0400
+++ b/cmd/wmii/screen.c Sun Oct 19 18:46:02 2008 -0400
@@ -79,6 +79,55 @@
}
#endif
+void*
+findthing(Rectangle rect, int direction, Vector_ptr *vec, Rectangle (*key)(void*)) {
+ Rectangle isect;
+ Rectangle r, bestisect, bestr;
+ void *best, *p;
+ int i, n;
+
+ best = nil;
+#define frob(min, max, LT, x, y) \
+ if(D##y(isect) > 0) /* If they intersect at some point on this axis */ \
+ if(r.min.x LT rect.min.x) { \
+ n = abs(r.max.x - rect.min.x) - abs(bestr.max.x - rect.min.x); \
+ if(best == nil \
+ || n == 0 && D##y(isect) > D##y(bestisect) \
+ || n < 0 \
+ ) { \
+ best = p; \
+ bestr = r; \
+ bestisect = isect; \
+ } \
+ }
+
+ /* Variable hell? Certainly. */
+ for(i=0; i < vec->n; i++) {
+ p = vec->ary[i];
+ r = key(p);
+ isect = rect_intersection(rect, r);
+ switch(direction) {
+ default:
+ die("not reached");
+ /* Not reached */
+ case West:
+ frob(min, max, <, x, y);
+ break;
+ case East:
+ frob(max, min, >, x, y);
+ break;
+ case North:
+ frob(min, max, <, y, x);
+ break;
+ case South:
+ frob(max, min, >, y, x);
+ break;
+ }
+ }
+#undef frob
+ return best;
+}
+
int
ownerscreen(Rectangle r) {
Rectangle isect;
diff -r e7626a2b5aa0 -r 49001679f1bc cmd/wmii/view.c
--- a/cmd/wmii/view.c Sun Oct 19 12:32:46 2008 -0400
+++ b/cmd/wmii/view.c Sun Oct 19 18:46:02 2008 -0400
@@ -373,7 +373,7 @@
|| group_leader(c->group) && !client_viewframe(group_leader(c->group),
c->sel->view);
if(!(c->w.ewmh.type & (TypeSplash|TypeDock))) {
- if(newgroup)
+ if(newgroup && !(c->tagre.regex && regexec(c->tagre.regc, v->name, nil, 0)))
frame_focus(f);
else if(c->group && f->area->sel->client->group == c->group)
/* XXX: Stack. */
diff -r e7626a2b5aa0 -r 49001679f1bc cmd/wmii/x11.c
--- a/cmd/wmii/x11.c Sun Oct 19 12:32:46 2008 -0400
+++ b/cmd/wmii/x11.c Sun Oct 19 18:46:02 2008 -0400
@@ -903,6 +903,14 @@
XSetInputFocus(display, w->w, mode, CurrentTime);
}
+XWindow
+getfocus(void) {
+ XWindow ret, revert;
+
+ XGetInputFocus(display, &ret, &revert);
+ return ret;
+}
+
/* Mouse */
Point
querypointer(Window *w) {
diff -r e7626a2b5aa0 -r 49001679f1bc include/x11.h
--- a/include/x11.h Sun Oct 19 12:32:46 2008 -0400
+++ b/include/x11.h Sun Oct 19 18:46:02 2008 -0400
@@ -208,6 +208,7 @@
void freefont(Font*);
void freeimage(Image *);
void freestringlist(char**);
+XWindow getfocus(void);
ulong getprop_long(Window*, char*, char*, ulong, long**, ulong);
char* getprop_string(Window*, char*);
int getprop_textlist(Window *w, char *name, char **ret[]);
Received on Sun Oct 19 2008 - 22:46:04 UTC
This archive was generated by hypermail 2.2.0 : Sun Oct 19 2008 - 22:48:04 UTC