dwm

Kris's build of dwm
git clone git clone https://git.krisyotam.com/krisyotam/dwm.git
Log | Files | Refs | README | LICENSE

alttab.c (4652B)


      1 int alttabn;          /* move that many clients forward */
      2 int ntabs;            /* number of active clients in tag */
      3 int isalt;
      4 Client **altsnext;    /* array of all clients in the tag */
      5 Window alttabwin;
      6 
      7 void
      8 alttab()
      9 {
     10 	Monitor *m = selmon;
     11 
     12 	/* move to next window */
     13 	if (m->sel && m->sel->snext) {
     14 		alttabn++;
     15 		if (alttabn >= ntabs)
     16 			alttabn = 0; /* reset alttabn */
     17 
     18 		focus(altsnext[alttabn]);
     19 		restack(m);
     20 	}
     21 
     22 	/* redraw tab */
     23 	XRaiseWindow(dpy, alttabwin);
     24 	drawalttab(ntabs, 0, m);
     25 }
     26 
     27 void
     28 alttabend()
     29 {
     30 	Monitor *m = selmon;
     31 	Client *buff;
     32 	int i;
     33 
     34 	if (!isalt)
     35 		return;
     36 
     37 	/* Move all clients between first and choosen position,
     38 	 * one down in stack and put choosen client to the first position
     39 	 * so they remain in right order for the next time that alt-tab is used
     40 	 */
     41 	if (ntabs > 1) {
     42 		if (alttabn != 0) { /* if user picked original client do nothing */
     43 			buff = altsnext[alttabn];
     44 			if (alttabn > 1)
     45 				for (i = alttabn; i > 0; i--)
     46 					altsnext[i] = altsnext[i - 1];
     47 			else /* swap them if there are just 2 clients */
     48 				altsnext[alttabn] = altsnext[0];
     49 			altsnext[0] = buff;
     50 		}
     51 
     52 		/* restack clients */
     53 		for (i = ntabs - 1; i >= 0; i--) {
     54 		    focus(altsnext[i]);
     55 		    restack(m);
     56 		}
     57 
     58 		free(altsnext); /* free list of clients */
     59 	}
     60 
     61 	/* destroy the window */
     62 	isalt = 0;
     63 	ntabs = 0;
     64 	XUnmapWindow(dpy, alttabwin);
     65 	XDestroyWindow(dpy, alttabwin);
     66 }
     67 
     68 void
     69 drawalttab(int nwins, int first, Monitor *m)
     70 {
     71 	Client *c;
     72 	int i, h;
     73 	int y = 0;
     74 	int px = m->mx;
     75 	int py = m->my;
     76 
     77 	if (first) {
     78 		XSetWindowAttributes wa = {
     79 			.override_redirect = True,
     80 			#if BAR_ALPHA_PATCH
     81 			.background_pixel = 0,
     82 			.border_pixel = 0,
     83 			.colormap = cmap,
     84 			#else
     85 			.background_pixmap = ParentRelative,
     86 			#endif // BAR_ALPHA_PATCH
     87 			.event_mask = ButtonPressMask|ExposureMask
     88 		};
     89 
     90 		/* decide position of tabwin */
     91 		if (tabposx == 1)
     92 			px = m->mx + (m->mw / 2) - (maxwtab / 2);
     93 		else if (tabposx == 2)
     94 			px = m->mx + m->mw - maxwtab;
     95 
     96 		if (tabposy == 1)
     97 			py = m->my + (m->mh / 2) - (maxhtab / 2);
     98 		else if (tabposy == 2)
     99 			py = m->my + m->mh - maxhtab;
    100 
    101 		h = maxhtab;
    102 
    103 		#if BAR_ALPHA_PATCH
    104 		alttabwin = XCreateWindow(dpy, root, px, py, maxwtab, maxhtab, 2, depth,
    105 		                             InputOutput, visual,
    106 		                             CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa);
    107 		#else
    108 		alttabwin = XCreateWindow(dpy, root, px, py, maxwtab, maxhtab, 2, DefaultDepth(dpy, screen),
    109 		                             CopyFromParent, DefaultVisual(dpy, screen),
    110 		                             CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
    111 		#endif // BAR_ALPHA_PATCH
    112 
    113 		XDefineCursor(dpy, alttabwin, cursor[CurNormal]->cursor);
    114 		XMapRaised(dpy, alttabwin);
    115 	}
    116 
    117 	h = maxhtab / ntabs;
    118 	for (i = 0; i < ntabs; i++) { /* draw all clients into tabwin */
    119 		c = altsnext[i];
    120 		if (!ISVISIBLE(c))
    121 			continue;
    122 		if (HIDDEN(c))
    123 			continue;
    124 
    125 		drw_setscheme(drw, scheme[c == m->sel ? SchemeSel : SchemeNorm]);
    126 		drw_text(drw, 0, y, maxwtab, h, 0, c->name, 0, 0);
    127 		y += h;
    128 	}
    129 
    130 	drw_setscheme(drw, scheme[SchemeNorm]);
    131 	drw_map(drw, alttabwin, 0, 0, maxwtab, maxhtab);
    132 }
    133 
    134 void
    135 alttabstart(const Arg *arg)
    136 {
    137 	Client *c;
    138 	Monitor *m = selmon;
    139 	int grabbed;
    140 	int i;
    141 
    142 	altsnext = NULL;
    143 	if (alttabwin)
    144 		alttabend();
    145 
    146 	if (isalt == 1) {
    147 		alttabend();
    148 		return;
    149 	}
    150 
    151 	isalt = 1;
    152 	alttabn = 0;
    153 	ntabs = 0;
    154 
    155 	for (c = m->clients; c; c = c->next) {
    156 		if (!ISVISIBLE(c))
    157 			continue;
    158 		if (HIDDEN(c))
    159 			continue;
    160 
    161 		++ntabs;
    162 	}
    163 
    164 	if (!ntabs) {
    165 		alttabend();
    166 		return;
    167 	}
    168 
    169 	altsnext = (Client **) malloc(ntabs * sizeof(Client *));
    170 
    171 	for (i = 0, c = m->stack; c; c = c->snext) {
    172 		if (!ISVISIBLE(c))
    173 			continue;
    174 		if (HIDDEN(c))
    175 			continue;
    176 
    177 		altsnext[i] = c;
    178 		i++;
    179 	}
    180 
    181 	drawalttab(ntabs, 1, m);
    182 
    183 	struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 };
    184 
    185 	/* grab keyboard (take all input from keyboard) */
    186 	grabbed = 1;
    187 	for (i = 0; i < 1000; i++) {
    188 		if (XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess)
    189 			break;
    190 		nanosleep(&ts, NULL);
    191 		if (i == 1000 - 1)
    192 			grabbed = 0;
    193 	}
    194 
    195 	XEvent event;
    196 	alttab();
    197 
    198 	if (grabbed == 0) {
    199 		alttabend();
    200 		return;
    201 	}
    202 
    203 	while (grabbed) {
    204 		XNextEvent(dpy, &event);
    205 		if (event.type == KeyPress || event.type == KeyRelease) {
    206 			if (event.type == KeyRelease && event.xkey.keycode == tabmodkey) /* if mod key is released break cycle */
    207 				break;
    208 
    209 			if (event.type == KeyPress) {
    210 				if (event.xkey.keycode == tabcyclekey) { /* if tab is pressed move to the next window */
    211 					alttab();
    212 				}
    213 			}
    214 		}
    215 	}
    216 
    217 	c = m->sel;
    218 	alttabend();
    219 
    220 	XUngrabKeyboard(dpy, CurrentTime);
    221 	focus(c);
    222 	restack(m);
    223 }