diff -r f8c445284353 -r a3c47fa966ee config.def.h --- a/config.def.h Fri Jul 18 20:18:45 2008 +0100 +++ b/config.def.h Tue Jul 22 11:21:22 2008 +0300 @@ -67,6 +67,8 @@ static Key keys[] = { { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, { MODKEY, XK_0, view, {.ui = ~0 } }, { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, + { MODKEY, XK_Left, view_prev_tag, {0} }, + { MODKEY, XK_Right, view_next_tag, {0} }, TAGKEYS( XK_1, 0) TAGKEYS( XK_2, 1) TAGKEYS( XK_3, 2) diff -r f8c445284353 -r a3c47fa966ee dwm.1 --- a/dwm.1 Fri Jul 18 20:18:45 2008 +0100 +++ b/dwm.1 Tue Jul 22 11:21:22 2008 +0300 @@ -117,6 +117,14 @@ tag. .B Mod1\-0 View all windows with any tag. .TP +.B Mod1\-Left +View all windows with tag previous than current. E.g. +if tag 4 is selected, previous tag would be 3. +.TP +.B Mod1\-Right +View all windows with tag next than current. E.g. +if tag 4 is selected, next tag would be 5. +.TP .B Mod1\-Control\-[1..n] Add/remove all windows with .BR nth diff -r f8c445284353 -r a3c47fa966ee dwm.c --- a/dwm.c Fri Jul 18 20:18:45 2008 +0100 +++ b/dwm.c Tue Jul 22 11:21:22 2008 +0300 @@ -197,6 +197,9 @@ static void updatetitle(Client *c); static void updatetitle(Client *c); static void updatewmhints(Client *c); static void view(const Arg *arg); +static void view_next_tag(const Arg *); +static void view_prev_tag(const Arg *); +static void view_adjacent_tag(int); static int xerror(Display *dpy, XErrorEvent *ee); static int xerrordummy(Display *dpy, XErrorEvent *ee); static int xerrorstart(Display *dpy, XErrorEvent *ee); @@ -1672,6 +1675,66 @@ view(const Arg *arg) { arrange(); } +/* + * Views adjacent tag based on current selected + * tag(s) and distance. Distance is expressed + * as relative to first selected tag(s), for + * example if first selected tag is 4 and + * distance is +2 then we display tag 4 + 2 = 6. + * + * Note that this function only selects one tag + * even though user has multiple tags selected + * before. + */ +static void +view_adjacent_tag(int distance) +{ + int i, curtags; + int seltag = 0; + Arg arg; + + /* + * Check first tag currently selected. If there are + * several tags selected we only pick first one. + */ + curtags = (tagset[seltags] & TAGMASK); + for (i = 0; i < LENGTH(tags); i++) { + if ((curtags & (1 << i)) != 0) { + seltag = i; + break; + } + } + + /* + * Calculate next selected tag wrapping around + * when tag overflows. + */ + seltag = (seltag + distance) % (int)LENGTH(tags); + if (seltag < 0) + seltag += LENGTH(tags); + + arg.i = (1 << seltag); + view(&arg); +} + +/*ARGSUSED*/ +static void +view_next_tag(const Arg *arg) +{ + (void)arg; + + view_adjacent_tag(+1); +} + +/*ARGSUSED*/ +static void +view_prev_tag(const Arg *arg) +{ + (void)arg; + + view_adjacent_tag(-1); +} + /* There's no way to check accesses to destroyed windows, thus those cases are * ignored (especially on UnmapNotify's). Other types of errors call Xlibs * default error handler, which may call exit. */