sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

dwm-alttab2+winview-6.4.diff (5898B)


      1 diff --git a/config.def.h b/config.def.h
      2 index 9efa774..95499bd 100644
      3 --- a/config.def.h
      4 +++ b/config.def.h
      5 @@ -2,6 +2,8 @@
      6  
      7  /* appearance */
      8  static const unsigned int borderpx  = 1;        /* border pixel of windows */
      9 +static const unsigned int tabModKey = 0x40;
     10 +static const unsigned int tabCycleKey = 0x17;
     11  static const unsigned int snap      = 32;       /* snap pixel */
     12  static const int showbar            = 1;        /* 0 means no bar */
     13  static const int topbar             = 1;        /* 0 means bottom bar */
     14 @@ -95,6 +97,8 @@ static const Key keys[] = {
     15  	TAGKEYS(                        XK_8,                      7)
     16  	TAGKEYS(                        XK_9,                      8)
     17  	{ MODKEY|ShiftMask,             XK_q,      quit,           {0} },
     18 +	{ MODKEY,                       XK_o,      winview,        {0} },
     19 +	{ Mod1Mask,                     XK_Tab,    alttab,         {0} },
     20  };
     21  
     22  /* button definitions */
     23 diff --git a/dwm.1 b/dwm.1
     24 index ddc8321..f8a809e 100644
     25 --- a/dwm.1
     26 +++ b/dwm.1
     27 @@ -110,6 +110,9 @@ Increase master area size.
     28  .B Mod1\-h
     29  Decrease master area size.
     30  .TP
     31 +.B Mod1\-o
     32 +Select view of the window in focus. The list of tags to be displayed is matched to the window tag list.
     33 +.TP
     34  .B Mod1\-Return
     35  Zooms/cycles focused window to/from master area (tiled layouts only).
     36  .TP
     37 diff --git a/dwm.c b/dwm.c
     38 index f1d86b2..71d0ebc 100644
     39 --- a/dwm.c
     40 +++ b/dwm.c
     41 @@ -28,6 +28,7 @@
     42  #include <stdlib.h>
     43  #include <string.h>
     44  #include <unistd.h>
     45 +#include <time.h>
     46  #include <sys/types.h>
     47  #include <sys/wait.h>
     48  #include <X11/cursorfont.h>
     49 @@ -142,6 +143,7 @@ typedef struct {
     50  } Rule;
     51  
     52  /* function declarations */
     53 +static void alttab(const Arg *arg);
     54  static void applyrules(Client *c);
     55  static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
     56  static void arrange(Monitor *m);
     57 @@ -168,6 +170,7 @@ static void expose(XEvent *e);
     58  static void focus(Client *c);
     59  static void focusin(XEvent *e);
     60  static void focusmon(const Arg *arg);
     61 +static void focusnext(const Arg *arg);
     62  static void focusstack(const Arg *arg);
     63  static Atom getatomprop(Client *c, Atom prop);
     64  static int getrootptr(int *x, int *y);
     65 @@ -229,6 +232,7 @@ static void updatewmhints(Client *c);
     66  static void view(const Arg *arg);
     67  static Client *wintoclient(Window w);
     68  static Monitor *wintomon(Window w);
     69 +static void winview(const Arg* arg);
     70  static int xerror(Display *dpy, XErrorEvent *ee);
     71  static int xerrordummy(Display *dpy, XErrorEvent *ee);
     72  static int xerrorstart(Display *dpy, XErrorEvent *ee);
     73 @@ -268,6 +272,8 @@ static Drw *drw;
     74  static Monitor *mons, *selmon;
     75  static Window root, wmcheckwin;
     76  
     77 +static int alt_tab_direction = 0;
     78 +
     79  /* configuration, allows nested code to access above variables */
     80  #include "config.h"
     81  
     82 @@ -275,6 +281,79 @@ static Window root, wmcheckwin;
     83  struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
     84  
     85  /* function implementations */
     86 +
     87 +static void
     88 +alttab(const Arg *arg) {
     89 +
     90 +	view(&(Arg){ .ui = ~0 });
     91 +	focusnext(&(Arg){ .i = alt_tab_direction });
     92 +
     93 +	int grabbed = 1;
     94 +	int grabbed_keyboard = 1000;
     95 +	for (int i = 0; i < 100; i += 1) {
     96 +		struct timespec ts;
     97 +		ts.tv_sec = 0;
     98 +		ts.tv_nsec = 1000000;
     99 +
    100 +		if (grabbed_keyboard != GrabSuccess) {
    101 +			grabbed_keyboard = XGrabKeyboard(dpy, DefaultRootWindow(dpy), True,
    102 +											 GrabModeAsync, GrabModeAsync, CurrentTime);
    103 +		}
    104 +		if (grabbed_keyboard == GrabSuccess) {
    105 +			XGrabButton(dpy, AnyButton, AnyModifier, None, False,
    106 +						BUTTONMASK, GrabModeAsync, GrabModeAsync,
    107 +						None, None);
    108 +			break;
    109 +		}
    110 +		nanosleep(&ts, NULL);
    111 +		if (i == 100 - 1)
    112 +			grabbed = 0;
    113 +	}
    114 +
    115 +	XEvent event;
    116 +	Client *c;
    117 +	Monitor *m;
    118 +	XButtonPressedEvent *ev;
    119 +
    120 +	while (grabbed) {
    121 +		XNextEvent(dpy, &event);
    122 +		switch (event.type) {
    123 +		case KeyPress:
    124 +			if (event.xkey.keycode == tabCycleKey)
    125 +				focusnext(&(Arg){ .i = alt_tab_direction });
    126 +			break;
    127 +		case KeyRelease:
    128 +			if (event.xkey.keycode == tabModKey) {
    129 +				XUngrabKeyboard(dpy, CurrentTime);
    130 +				XUngrabButton(dpy, AnyButton, AnyModifier, None);
    131 +				grabbed = 0;
    132 +				alt_tab_direction = !alt_tab_direction;
    133 +				winview(0);
    134 +			}
    135 +			break;
    136 +	    case ButtonPress:
    137 +			ev = &(event.xbutton);
    138 +			if ((m = wintomon(ev->window)) && m != selmon) {
    139 +				unfocus(selmon->sel, 1);
    140 +				selmon = m;
    141 +				focus(NULL);
    142 +			}
    143 +			if ((c = wintoclient(ev->window)))
    144 +				focus(c);
    145 +			XAllowEvents(dpy, AsyncBoth, CurrentTime);
    146 +			break;
    147 +		case ButtonRelease:
    148 +			XUngrabKeyboard(dpy, CurrentTime);
    149 +			XUngrabButton(dpy, AnyButton, AnyModifier, None);
    150 +			grabbed = 0;
    151 +			alt_tab_direction = !alt_tab_direction;
    152 +			winview(0);
    153 +			break;
    154 +		}
    155 +	}
    156 +	return;
    157 +}
    158 +
    159  void
    160  applyrules(Client *c)
    161  {
    162 @@ -835,6 +914,28 @@ focusmon(const Arg *arg)
    163  	focus(NULL);
    164  }
    165  
    166 +static void
    167 +focusnext(const Arg *arg) {
    168 +	Monitor *m;
    169 +	Client *c;
    170 +	m = selmon;
    171 +	c = m->sel;
    172 +
    173 +	if (arg->i) {
    174 +		if (c->next)
    175 +			c = c->next;
    176 +		else
    177 +			c = m->clients;
    178 +	} else {
    179 +		Client *last = c;
    180 +		if (last == m->clients)
    181 +			last = NULL;
    182 +		for (c = m->clients; c->next != last; c = c->next);
    183 +	}
    184 +	focus(c);
    185 +	return;
    186 +}
    187 +
    188  void
    189  focusstack(const Arg *arg)
    190  {
    191 @@ -2092,6 +2193,26 @@ wintomon(Window w)
    192  	return selmon;
    193  }
    194  
    195 +/* Selects for the view of the focused window. The list of tags */
    196 +/* to be displayed is matched to the focused window tag list. */
    197 +void
    198 +winview(const Arg* arg){
    199 +	Window win, win_r, win_p, *win_c;
    200 +	unsigned nc;
    201 +	int unused;
    202 +	Client* c;
    203 +	Arg a;
    204 +
    205 +	if (!XGetInputFocus(dpy, &win, &unused)) return;
    206 +	while(XQueryTree(dpy, win, &win_r, &win_p, &win_c, &nc)
    207 +	      && win_p != win_r) win = win_p;
    208 +
    209 +	if (!(c = wintoclient(win))) return;
    210 +
    211 +	a.ui = c->tags;
    212 +	view(&a);
    213 +}
    214 +
    215  /* There's no way to check accesses to destroyed windows, thus those cases are
    216   * ignored (especially on UnmapNotify's). Other types of errors call Xlibs
    217   * default error handler, which may call exit. */