On Fri, May 23, 2008 at 9:54 AM, John Li <[EMAIL PROTECTED]> wrote:
> On Fri, May 23, 2008 at 02:47:28PM +0200, Jan Christoph Ebersbach wrote:
> > On Sun 18-05-2008 12:42 +0200, Anselm R. Garbe wrote:
> > > On Sun, May 18, 2008 at 12:07:37PM +0200, Jan Christoph Ebersbach
> > > wrote:
> > > > The floating layout is totally useless when it comes to mouseless
> > > > usage and even with the mouse there is no window manager that
> > > > provides such weak functionality to manage floating windows.
> > >
> > > I disagree. I think the floating mode is as usable as in traditional
> > > WMs -- which functionality are you missing?
> >
> > Pancake guessed right, I was talking about maximizing, moving and
> > resizing windows. It would also be nice to have an arrange and/or an
> > overview like the one MacOS provides.
>
> Curious you ask for the Mac OS exposé thing. I was observing that
> setting a non-floating layout and selecting all tags essentially gives
> you this. I think what would make it perfect would be the "grid-mode"
> layout from a while ago (I don't know if it still works) so that you
> don't have one huge master window and a bunch of very short (or skinny)
> windows in the tile area.
>
> But (and this is somewhat of a problem with automatic tiling in general)
> it can be hard to distinguish windows when the geometric information
> (width, height) is removed. I think having everything in a grid would
> still be kind of nice.
>
>
> -John
>
I saw this and got curious. This is a quick and dirty patch I whipped up,
but I like the way it works. Beware it also has and extra layout and
pointer
warping because I was too lazy to get rid of them to make the diff. I've
also
included my config.h so you can see how I use it to move horizontally while
in grid mode.
grid() - obviously the grid layout
viewtagsel() - view tags of selected client, to come out of expose mode
focus{next,prev}() - now take an argument, the number of clients to jump or
if the argument is NULL, it jumps `rows` clients. (really dirty hack
because
I'm lazy)
This patches against the current tip, changeset 1234
-E
-E
diff -r ec42705c5fac config.mk
--- a/config.mk Thu May 22 14:15:30 2008 +0100
+++ b/config.mk Fri May 23 11:16:17 2008 -0700
@@ -22,7 +22,7 @@ CPPFLAGS = -DVERSION=\"${VERSION}\" ${XI
CPPFLAGS = -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
#CFLAGS = -Os ${INCS} ${CPPFLAGS}
#LDFLAGS = -s ${LIBS}
-CFLAGS = -g -std=c99 -pedantic -Wall -O2 ${INCS} ${CPPFLAGS}
+CFLAGS = -g -std=c99 -pedantic -Wall ${INCS} ${CPPFLAGS}
LDFLAGS = -g ${LIBS}
# Solaris
diff -r ec42705c5fac dwm.c
--- a/dwm.c Thu May 22 14:15:30 2008 +0100
+++ b/dwm.c Fri May 23 16:39:38 2008 -0700
@@ -124,6 +124,7 @@ void buttonpress(XEvent *e);
void buttonpress(XEvent *e);
void checkotherwm(void);
void cleanup(void);
+void col(void);
void configure(Client *c);
void configurenotify(XEvent *e);
void configurerequest(XEvent *e);
@@ -146,6 +147,7 @@ Bool gettextprop(Window w, Atom atom, ch
Bool gettextprop(Window w, Atom atom, char *text, uint size);
void grabbuttons(Client *c, Bool focused);
void grabkeys(void);
+void grid(void);
void initfont(const char *fontstr);
Bool isoccupied(uint t);
Bool isprotodel(Client *c);
@@ -189,6 +191,7 @@ void updatewmhints(Client *c);
void updatewmhints(Client *c);
void view(const void *arg);
void viewprevtag(const void *arg);
+void viewtagsel(const void *arg);
int xerror(Display *dpy, XErrorEvent *ee);
int xerrordummy(Display *dpy, XErrorEvent *ee);
int xerrorstart(Display *dpy, XErrorEvent *ee);
@@ -199,6 +202,7 @@ int screen, sx, sy, sw, sh;
int screen, sx, sy, sw, sh;
int bx, by, bw, bh, blw, wx, wy, ww, wh;
int mx, my, mw, mh, tx, ty, tw, th;
+int rows = 1;
uint seltags = 0;
int (*xerrorxlib)(Display *, XErrorEvent *);
uint numlockmask = 0;
@@ -389,6 +393,26 @@ cleanup(void) {
}
void
+col(void) {
+ int x, y, h, w;
+ uint i, n;
+ Client *c;
+
+ for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next), n++);
+ if(n == 0)
+ return;
+
+ w = (n < 3) ? ww / n : ww / 3;
+
+ for(i = 0, c = nexttiled(clients); c; c = nexttiled(c->next), i++) {
+ h = (i < 2) ? wh : wh / (n-2);
+ x = wx + ((i < 2) ? i * w : 2 * w);
+ y = wy + ((i < 3) ? 0 : h * (i-2));
+ tileresize(c, x, y, w - 2 * c->bw, h - 2 * c->bw);
+ }
+}
+
+void
configure(Client *c) {
XConfigureEvent ce;
@@ -660,32 +684,43 @@ void
void
focusnext(const void *arg) {
Client *c;
+ uint i;
if(!sel)
return;
- for(c = sel->next; c && !VISIBLE(c); c = c->next);
- if(!c)
- for(c = clients; c && !VISIBLE(c); c = c->next);
- if(c) {
- focus(c);
- restack();
+ if(!arg)
+ arg = (void *)rows;
+
+ for(i = 0; i < (uint) arg; i++) {
+ for(c = sel->next; c && !VISIBLE(c); c = c->next);
+ if(!c)
+ for(c = clients; c && !VISIBLE(c); c = c->next);
+ if(c) {
+ focus(c);
+ restack();
+ }
}
}
void
focusprev(const void *arg) {
Client *c;
+ uint i;
if(!sel)
return;
- for(c = sel->prev; c && !VISIBLE(c); c = c->prev);
- if(!c) {
- for(c = clients; c && c->next; c = c->next);
- for(; c && !VISIBLE(c); c = c->prev);
- }
- if(c) {
- focus(c);
- restack();
+ if(!arg)
+ arg = (void *)rows;
+ for(i = 0; i < (uint) arg; i++) {
+ for(c = sel->prev; c && !VISIBLE(c); c = c->prev);
+ if(!c) {
+ for(c = clients; c && c->next; c = c->next);
+ for(; c && !VISIBLE(c); c = c->prev);
+ }
+ if(c) {
+ focus(c);
+ restack();
+ }
}
}
@@ -1196,6 +1231,10 @@ restack(void) {
drawbar();
if(!sel)
return;
+
+ XWarpPointer(dpy, None, RootWindow(dpy, DefaultScreen(dpy)), 0, 0, 0, 0, sel->x + sel->w / 2, sel->y + sel->h / 2);
+ XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
+
if(sel->isfloating || !lt->arrange)
XRaiseWindow(dpy, sel->win);
if(lt->arrange) {
@@ -1445,6 +1484,29 @@ textw(const char *text) {
}
void
+grid(void) {
+ int x, y, h, w, cols;
+ uint i, n;
+ Client *c;
+
+ for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next), n++);
+ if(n == 0)
+ return;
+
+ for(cols = 0; cols * cols < n; cols++);
+ rows = n / cols + !!(n % cols);
+
+ h = wh / rows;
+ w = ww / cols;
+
+ for(i = 0, c = nexttiled(clients); c; c = nexttiled(c->next), i++) {
+ x = wx + i / rows * w;
+ y = wy + i % rows * h;
+ tileresize(c, x, y, w - 2 * c->bw, h - 2 * c->bw);
+ }
+}
+
+void
tile(void) {
int x, y, h, w;
uint i, n;
@@ -1728,6 +1790,13 @@ viewprevtag(const void *arg) {
viewprevtag(const void *arg) {
seltags ^= 1; /* toggle sel tagset */
arrange();
+}
+
+void
+viewtagsel(const void *arg) {
+ if(!sel)
+ return;
+ view((uint[]){ sel->tags });
}
/* There's no way to check accesses to destroyed windows, thus those cases are
/* See LICENSE file for copyright and license details. */
/* appearance */
#define FONT "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*"
#define NORMBORDERCOLOR "#333333"
#define NORMBGCOLOR "#000000"
#define NORMFGCOLOR "#00ff00"
#define SELBORDERCOLOR "#ff0000"
#define SELBGCOLOR "#000000"
#define SELFGCOLOR "#ff0000"
unsigned int borderpx = 1; /* border pixel of windows */
unsigned int snap = 32; /* snap pixel */
Bool showbar = True; /* False means no bar */
Bool topbar = True; /* False means bottom bar */
/* tagging */
const char tags[][MAXTAGLEN] = { "code", "debug", "browser", "IM", "mail", "docs" };
Rule rules[] = {
/* class instance title tags ref isfloating */
{ "Firefox", NULL, NULL, 1 << 2, False},
{ "Gaim", NULL, NULL, 1 << 3, False},
{ "Multi", NULL, NULL, 1 << 1, False},
{ "Mprojmgr", NULL, NULL, 1 << 1, False},
{ "Xpdf", NULL, NULL, 1 << 5, False},
};
/* layout(s) */
double mfact = 0.66;
Bool resizehints = False; /* False means respect size hints in tiled resizals */
Layout layouts[] = {
/* symbol arrange geom */
{ "[]=", tile, updatetilegeom }, /* first entry is default */
{ "+++", grid, updatetilegeom },
{ "|||", col, updatetilegeom }, /* first entry is default */
{ "><>", NULL, NULL }, /* no layout function means floating behavior */
};
/* key definitions */
#define MODKEY Mod1Mask
Key keys[] = {
/* modifier key function argument */
{ MODKEY, XK_p, spawn, (char *)"exec dmenu_run -fn '"FONT"' -nb '"NORMBGCOLOR"' -nf '"NORMFGCOLOR"' -sb '"SELBGCOLOR"' -sf '"SELFGCOLOR"'" },
{ MODKEY|ShiftMask, XK_Return, spawn, (char *)"exec uxterm" },
{ MODKEY, XK_b, togglebar, NULL },
{ MODKEY, XK_j, focusnext, (void *) 1 },
{ MODKEY, XK_k, focusprev, (void *) 1 },
{ MODKEY, XK_l, focusnext, NULL },
{ MODKEY, XK_h, focusprev, NULL },
{ MODKEY|ShiftMask, XK_h, setmfact, (double[]){-0.05} },
{ MODKEY|ShiftMask, XK_l, setmfact, (double[]){+0.05} },
{ MODKEY, XK_Return, zoom, NULL },
{ MODKEY, XK_Tab, viewprevtag, NULL },
{ MODKEY|ShiftMask, XK_c, killclient, NULL },
{ MODKEY, XK_space, togglelayout, NULL },
{ MODKEY|ShiftMask, XK_space, togglefloating, NULL },
{ MODKEY, XK_x, viewtagsel, NULL },
{ MODKEY, XK_x, togglelayout, "|||" },
{ MODKEY, XK_0, togglelayout, "+++" },
{ MODKEY, XK_0, view, (uint[]){ ~0 } },
{ MODKEY, XK_a, view, (uint[]){ 1 << 0 } },
{ MODKEY, XK_s, view, (uint[]){ 1 << 1 } },
{ MODKEY, XK_d, view, (uint[]){ 1 << 2 } },
{ MODKEY, XK_q, view, (uint[]){ 1 << 3 } },
{ MODKEY, XK_w, view, (uint[]){ 1 << 4 } },
{ MODKEY, XK_e, view, (uint[]){ 1 << 5 } },
{ MODKEY|ControlMask, XK_a, toggleview, (uint[]){ 1 << 0 } },
{ MODKEY|ControlMask, XK_s, toggleview, (uint[]){ 1 << 1 } },
{ MODKEY|ControlMask, XK_d, toggleview, (uint[]){ 1 << 2 } },
{ MODKEY|ControlMask, XK_q, toggleview, (uint[]){ 1 << 3 } },
{ MODKEY|ControlMask, XK_w, toggleview, (uint[]){ 1 << 4 } },
{ MODKEY|ControlMask, XK_e, toggleview, (uint[]){ 1 << 5 } },
{ MODKEY|ShiftMask, XK_0, tag, (uint[]){ ~0 } },
{ MODKEY|ShiftMask, XK_a, tag, (uint[]){ 1 << 0 } },
{ MODKEY|ShiftMask, XK_s, tag, (uint[]){ 1 << 1 } },
{ MODKEY|ShiftMask, XK_d, tag, (uint[]){ 1 << 2 } },
{ MODKEY|ShiftMask, XK_q, tag, (uint[]){ 1 << 3 } },
{ MODKEY|ShiftMask, XK_w, tag, (uint[]){ 1 << 4 } },
{ MODKEY|ShiftMask, XK_e, tag, (uint[]){ 1 << 5 } },
{ MODKEY|ControlMask|ShiftMask, XK_a, toggletag, (uint[]){ 1 << 0 } },
{ MODKEY|ControlMask|ShiftMask, XK_s, toggletag, (uint[]){ 1 << 1 } },
{ MODKEY|ControlMask|ShiftMask, XK_d, toggletag, (uint[]){ 1 << 2 } },
{ MODKEY|ControlMask|ShiftMask, XK_q, toggletag, (uint[]){ 1 << 3 } },
{ MODKEY|ControlMask|ShiftMask, XK_w, toggletag, (uint[]){ 1 << 4 } },
{ MODKEY|ControlMask|ShiftMask, XK_e, toggletag, (uint[]){ 1 << 5 } },
};