tag.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /*
  2. * wmfs2 by Martin Duquesnoy <xorg62@gmail.com> { for(i = 2011; i < 2111; ++i) ©(i); }
  3. * For license, see COPYING.
  4. */
  5. #include <X11/Xutil.h> /* IconicState / NormalState */
  6. #include "tag.h"
  7. #include "util.h"
  8. #include "infobar.h"
  9. #include "client.h"
  10. #include "config.h"
  11. #include "barwin.h"
  12. #include "ewmh.h"
  13. #include "layout.h"
  14. struct tag*
  15. tag_new(struct screen *s, char *name)
  16. {
  17. struct tag *t, *l;
  18. t = xcalloc(1, sizeof(struct tag));
  19. t->screen = s;
  20. t->name = xstrdup(name);
  21. t->flags = 0;
  22. t->id = 0;
  23. t->sel = NULL;
  24. t->prev = NULL;
  25. if((l = TAILQ_LAST(&s->tags, tsub)))
  26. t->id = l->id + 1;
  27. SLIST_INIT(&t->clients);
  28. TAILQ_INIT(&t->sets);
  29. TAILQ_INSERT_TAIL(&s->tags, t, next);
  30. return t;
  31. }
  32. void
  33. tag_screen(struct screen *s, struct tag *t)
  34. {
  35. if(t == s->seltag)
  36. t = t->prev;
  37. if(!t)
  38. t = TAILQ_FIRST(&s->tags);
  39. t->prev = s->seltag;
  40. s->seltag = t;
  41. clients_arrange_map();
  42. if(!SLIST_EMPTY(&t->clients) && !(W->flags & WMFS_SCAN))
  43. client_focus( client_tab_next(t->sel));
  44. infobar_elem_screen_update(s, ElemTag);
  45. ewmh_update_wmfs_props();
  46. }
  47. /* Set t to NULL to untag c from c->tag */
  48. void
  49. tag_client(struct tag *t, struct client *c)
  50. {
  51. /* Remove client from its previous tag */
  52. if(c->tag && !(c->flags & CLIENT_RULED))
  53. {
  54. if(c->tag == t)
  55. return;
  56. if(!(c->flags & CLIENT_IGNORE_LAYOUT))
  57. layout_split_arrange_closed(c);
  58. if(!(c->flags & CLIENT_REMOVEALL))
  59. {
  60. SLIST_REMOVE(&c->tag->clients, c, client, tnext);
  61. if(c->tag->sel == c || W->client == c)
  62. client_focus( client_tab_next( client_next(c)));
  63. }
  64. }
  65. c->flags &= ~CLIENT_RULED;
  66. /* Client remove */
  67. if(!t)
  68. return;
  69. c->prevtag = c->tag;
  70. c->tag = t;
  71. c->screen = t->screen;
  72. client_update_props(c, CPROP_LOC);
  73. /*
  74. * Insert in new tag list before
  75. * layout_split_integrate, because of set historic.
  76. */
  77. SLIST_INSERT_HEAD(&t->clients, c, tnext);
  78. infobar_elem_screen_update(t->screen, ElemTag);
  79. if(c->flags & CLIENT_IGNORE_LAYOUT)
  80. c->flags ^= CLIENT_IGNORE_LAYOUT;
  81. else if(!(c->flags & CLIENT_TABBED))
  82. layout_split_integrate(c, t->sel);
  83. if(c->flags & CLIENT_TABMASTER && c->prevtag)
  84. {
  85. struct client *cc;
  86. SLIST_FOREACH(cc, &c->prevtag->clients, tnext)
  87. if(cc->tabmaster == c)
  88. tag_client(t, cc);
  89. }
  90. if(t != c->screen->seltag || c->flags & CLIENT_TABBED)
  91. client_unmap(c);
  92. }
  93. void
  94. uicb_tag_set(Uicb cmd)
  95. {
  96. int i = 0, n = ATOI(cmd);
  97. struct tag *t;
  98. TAILQ_FOREACH(t, &W->screen->tags, next)
  99. if(i++ == n)
  100. {
  101. tag_screen(W->screen, t);
  102. return;
  103. }
  104. }
  105. void
  106. uicb_tag_set_with_name(Uicb cmd)
  107. {
  108. struct tag *t;
  109. TAILQ_FOREACH(t, &W->screen->tags, next)
  110. if(!strcmp(cmd, t->name))
  111. {
  112. tag_screen(W->screen, t);
  113. return;
  114. }
  115. }
  116. void
  117. uicb_tag_next(Uicb cmd)
  118. {
  119. (void)cmd;
  120. struct tag *t;
  121. if((t = TAILQ_NEXT(W->screen->seltag, next)))
  122. tag_screen(W->screen, t);
  123. else if( /* CIRCULAR OPTION */ 1)
  124. tag_screen(W->screen, TAILQ_FIRST(&W->screen->tags));
  125. }
  126. void
  127. uicb_tag_prev(Uicb cmd)
  128. {
  129. (void)cmd;
  130. struct tag *t;
  131. if((t = TAILQ_PREV(W->screen->seltag, tsub, next)))
  132. tag_screen(W->screen, t);
  133. else if( /* CIRCULAR OPTION */ 1)
  134. tag_screen(W->screen, TAILQ_LAST(&W->screen->tags, tsub));
  135. }
  136. void
  137. uicb_tag_client(Uicb cmd)
  138. {
  139. struct tag *t;
  140. int id = ATOI(cmd);
  141. if((t = tag_gb_id(W->screen, id)))
  142. tag_client(t, W->client);
  143. }
  144. void
  145. uicb_tag_move_client_next(Uicb cmd)
  146. {
  147. (void)cmd;
  148. struct tag *t;
  149. if((t = TAILQ_NEXT(W->screen->seltag, next)))
  150. tag_client(t, W->client);
  151. else if( /* CIRCULAR OPTION */ 1)
  152. tag_client(TAILQ_FIRST(&W->screen->tags), W->client);
  153. }
  154. void
  155. uicb_tag_move_client_prev(Uicb cmd)
  156. {
  157. (void)cmd;
  158. struct tag *t;
  159. if((t = TAILQ_PREV(W->screen->seltag, tsub, next)))
  160. tag_client(t, W->client);
  161. else if( /* CIRCULAR OPTION */ 1)
  162. tag_client(TAILQ_LAST(&W->screen->tags, tsub), W->client);
  163. }
  164. void
  165. uicb_tag_click(Uicb cmd)
  166. {
  167. (void)cmd;
  168. struct tag *t;
  169. if((t = (struct tag*)W->last_clicked_barwin->ptr)
  170. && t->screen == W->screen)
  171. tag_screen(W->screen, t);
  172. }
  173. static void
  174. tag_remove(struct tag *t)
  175. {
  176. free(t->name);
  177. layout_free_set(t);
  178. free(t);
  179. }
  180. void
  181. tag_free(struct screen *s)
  182. {
  183. struct tag *t;
  184. TAILQ_FOREACH(t, &s->tags, next)
  185. {
  186. TAILQ_REMOVE(&s->tags, t, next);
  187. tag_remove(t);
  188. }
  189. }