My dwm build
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

234 lines
6.3 KiB

  1. --- dwm.c
  2. +++ dwm.c
  3. @@ -112,25 +112,35 @@ typedef struct {
  4. void (*arrange)(Monitor *);
  5. } Layout;
  6. +#define MAXTABS 50
  7. +
  8. +typedef struct Pertag Pertag;
  9. struct Monitor {
  10. char ltsymbol[16];
  11. float mfact;
  12. int nmaster;
  13. int num;
  14. int by; /* bar geometry */
  15. + int ty; /* tab bar geometry */
  16. int mx, my, mw, mh; /* screen size */
  17. int wx, wy, ww, wh; /* window area */
  18. unsigned int seltags;
  19. unsigned int sellt;
  20. unsigned int tagset[2];
  21. int showbar;
  22. + int showtab;
  23. int topbar;
  24. + int toptab;
  25. Client *clients;
  26. Client *sel;
  27. Client *stack;
  28. Monitor *next;
  29. Window barwin;
  30. + Window tabwin;
  31. + int ntabs;
  32. + int tab_widths[MAXTABS];
  33. const Layout *lt[2];
  34. + Pertag *pertag;
  35. };
  36. typedef struct {
  37. @@ -461,14 +488,33 @@ buttonpress(XEvent *e)
  38. click = ClkStatusText;
  39. else
  40. click = ClkWinTitle;
  41. - } else if ((c = wintoclient(ev->window))) {
  42. + }
  43. + if(ev->window == selmon->tabwin) {
  44. + i = 0; x = 0;
  45. + for(c = selmon->clients; c; c = c->next){
  46. + if(!ISVISIBLE(c)) continue;
  47. + x += selmon->tab_widths[i];
  48. + if (ev->x > x)
  49. + ++i;
  50. + else
  51. + break;
  52. + if(i >= m->ntabs) break;
  53. + }
  54. + if(c) {
  55. + click = ClkTabBar;
  56. + arg.ui = i;
  57. + }
  58. + }
  59. + else if((c = wintoclient(ev->window))) {
  60. focus(c);
  61. click = ClkClientWin;
  62. }
  63. - for (i = 0; i < LENGTH(buttons); i++)
  64. - if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
  65. - && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
  66. - buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg);
  67. + for(i = 0; i < LENGTH(buttons); i++)
  68. + if(click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
  69. + && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)){
  70. + buttons[i].func(((click == ClkTagBar || click == ClkTabBar)
  71. + && buttons[i].arg.i == 0) ? &arg : &buttons[i].arg);
  72. + }
  73. }
  74. void
  75. @@ -556,6 +605,8 @@ clientmessage(XEvent *e)
  76. if (!ISVISIBLE(c)) {
  77. c->mon->seltags ^= 1;
  78. c->mon->tagset[c->mon->seltags] = c->tags;
  79. + for(i=0; !(c->tags & 1 << i); i++);
  80. + view(&(Arg){.ui = 1 << i});
  81. }
  82. pop(c);
  83. }
  84. @@ -662,16 +711,41 @@ Monitor *
  85. createmon(void)
  86. {
  87. Monitor *m;
  88. + int i;
  89. m = ecalloc(1, sizeof(Monitor));
  90. m->tagset[0] = m->tagset[1] = 1;
  91. m->mfact = mfact;
  92. m->nmaster = nmaster;
  93. m->showbar = showbar;
  94. + m->showtab = showtab;
  95. m->topbar = topbar;
  96. - m->lt[0] = &layouts[0];
  97. + m->toptab = toptab;
  98. + m->ntabs = 0;
  99. + m->lt[0] = &layouts[def_layouts[1] % LENGTH(layouts)];
  100. m->lt[1] = &layouts[1 % LENGTH(layouts)];
  101. strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
  102. + if(!(m->pertag = (Pertag *)calloc(1, sizeof(Pertag))))
  103. + die("fatal: could not malloc() %u bytes\n", sizeof(Pertag));
  104. + m->pertag->curtag = m->pertag->prevtag = 1;
  105. + for(i=0; i <= LENGTH(tags); i++) {
  106. + /* init nmaster */
  107. + m->pertag->nmasters[i] = m->nmaster;
  108. +
  109. + /* init mfacts */
  110. + m->pertag->mfacts[i] = m->mfact;
  111. +
  112. + /* init layouts */
  113. + m->pertag->ltidxs[i][0] = &layouts[def_layouts[i % LENGTH(def_layouts)] % LENGTH(layouts)];
  114. + m->pertag->ltidxs[i][1] = m->lt[1];
  115. + m->pertag->sellts[i] = m->sellt;
  116. +
  117. + /* init showbar */
  118. + m->pertag->showbars[i] = m->showbar;
  119. +
  120. + /* swap focus and zoomswap*/
  121. + m->pertag->prevzooms[i] = NULL;
  122. + }
  123. return m;
  124. }
  125. @@ -1294,11 +1482,13 @@ movemouse(const Arg *arg)
  126. return;
  127. if (c->isfullscreen) /* no support moving fullscreen windows by mouse */
  128. return;
  129. + if(c->isfullscreen) /* no support moving fullscreen windows by mouse */
  130. + return;
  131. restack(selmon);
  132. ocx = c->x;
  133. ocy = c->y;
  134. if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
  135. - None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess)
  136. + None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess)
  137. return;
  138. if (!getrootptr(&x, &y))
  139. return;
  140. @@ -1454,11 +1646,13 @@ resizemouse(const Arg *arg)
  141. return;
  142. if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */
  143. return;
  144. + if(c->isfullscreen) /* no support resizing fullscreen windows by mouse */
  145. + return;
  146. restack(selmon);
  147. ocx = c->x;
  148. ocy = c->y;
  149. if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
  150. - None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess)
  151. + None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess)
  152. return;
  153. XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
  154. do {
  155. @@ -1615,11 +1810,11 @@ sendevent(Client *c, Atom proto)
  156. void
  157. setfocus(Client *c)
  158. {
  159. - if (!c->neverfocus) {
  160. + if(!c->neverfocus) {
  161. XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
  162. XChangeProperty(dpy, root, netatom[NetActiveWindow],
  163. - XA_WINDOW, 32, PropModeReplace,
  164. - (unsigned char *) &(c->win), 1);
  165. + XA_WINDOW, 32, PropModeReplace,
  166. + (unsigned char *) &(c->win), 1);
  167. }
  168. sendevent(c, wmatom[WMTakeFocus]);
  169. }
  170. @@ -1978,20 +2208,44 @@ updatebars(void)
  171. CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
  172. XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
  173. XMapRaised(dpy, m->barwin);
  174. + m->tabwin = XCreateWindow(dpy, root, m->wx, m->ty, m->ww, th, 0, DefaultDepth(dpy, screen),
  175. + CopyFromParent, DefaultVisual(dpy, screen),
  176. + CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
  177. + XDefineCursor(dpy, m->tabwin, cursor[CurNormal]->cursor);
  178. + XMapRaised(dpy, m->tabwin);
  179. }
  180. }
  181. void
  182. updatebarpos(Monitor *m)
  183. {
  184. + Client *c;
  185. + int nvis = 0;
  186. +
  187. m->wy = m->my;
  188. m->wh = m->mh;
  189. if (m->showbar) {
  190. m->wh -= bh;
  191. m->by = m->topbar ? m->wy : m->wy + m->wh;
  192. - m->wy = m->topbar ? m->wy + bh : m->wy;
  193. - } else
  194. + if ( m->topbar )
  195. + m->wy += bh;
  196. + } else {
  197. m->by = -bh;
  198. + }
  199. +
  200. + for(c = m->clients; c; c = c->next){
  201. + if(ISVISIBLE(c)) ++nvis;
  202. + }
  203. +
  204. + if(m->showtab == showtab_always
  205. + || ((m->showtab == showtab_auto) && (nvis > 1) && (m->lt[m->sellt]->arrange == monocle))){
  206. + m->wh -= th;
  207. + m->ty = m->toptab ? m->wy : m->wy + m->wh;
  208. + if ( m->toptab )
  209. + m->wy += th;
  210. + } else {
  211. + m->ty = -th;
  212. + }
  213. }
  214. void
  215. @@ -2173,9 +2427,9 @@ updatewindowtype(Client *c)
  216. Atom wtype = getatomprop(c, netatom[NetWMWindowType]);
  217. if (state == netatom[NetWMFullscreen])
  218. - setfullscreen(c, 1);
  219. + setfullscreen(c, True);
  220. if (wtype == netatom[NetWMWindowTypeDialog])
  221. - c->isfloating = 1;
  222. + c->isfloating = True;
  223. }
  224. void