Advertisement
Guest User

Untitled

a guest
Feb 18th, 2012
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.93 KB | None | 0 0
  1. --- dwm-6.0/dwm.c 2011-12-19 09:02:46.000000000 -0600
  2. +++ src/dwm-6.0/dwm.c 2011-12-31 18:41:07.804378632 -0600
  3. @@ -54,13 +54,17 @@
  4. #define HEIGHT(X) ((X)->h + 2 * (X)->bw)
  5. #define TAGMASK ((1 << LENGTH(tags)) - 1)
  6. #define TEXTW(X) (textnw(X, strlen(X)) + dc.font.height)
  7. +#define XEMBED_EMBEDDED_NOTIFY 0
  8. +#define IFREE(x) if(x) free(x)
  9. +#define zcalloc(size) calloc(1, (size))
  10. +#define ROOT RootWindow(dpy, DefaultScreen(dpy))
  11.  
  12. /* enums */
  13. enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
  14. enum { ColBorder, ColFG, ColBG, ColLast }; /* color */
  15. enum { NetSupported, NetWMName, NetWMState,
  16. NetWMFullscreen, NetActiveWindow, NetWMWindowType,
  17. - NetWMWindowTypeDialog, NetLast }; /* EWMH atoms */
  18. + NetWMWindowTypeDialog,NetSystemTray, NetLast }; /* EWMH atoms */
  19. enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
  20. enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
  21. ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
  22. @@ -143,6 +147,7 @@
  23. Monitor *next;
  24. Window barwin;
  25. const Layout *lt[2];
  26. + int primary;
  27. };
  28.  
  29. typedef struct {
  30. @@ -154,6 +159,13 @@
  31. int monitor;
  32. } Rule;
  33.  
  34. +typedef struct Systray Systray;
  35. +struct Systray {
  36. + Window win;
  37. + XRectangle geo;
  38. + Systray *next, *prev;
  39. +};
  40. +
  41. /* function declarations */
  42. static void applyrules(Client *c);
  43. static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact);
  44. @@ -170,7 +182,7 @@
  45. static void configure(Client *c);
  46. static void configurenotify(XEvent *e);
  47. static void configurerequest(XEvent *e);
  48. -static Monitor *createmon(void);
  49. +static Monitor *createmon(int primary);
  50. static void destroynotify(XEvent *e);
  51. static void detach(Client *c);
  52. static void detachstack(Client *c);
  53. @@ -252,6 +264,14 @@
  54. static int xerrorstart(Display *dpy, XErrorEvent *ee);
  55. static void zoom(const Arg *arg);
  56.  
  57. +static Bool systray_acquire(void);
  58. +static void systray_add(Window win);
  59. +static void systray_del(Systray *s);
  60. +static void systray_freeicons(void);
  61. +static Systray *systray_find(Window win);
  62. +static int systray_get_width(void);
  63. +static void systray_update(void);
  64. +
  65. /* variables */
  66. static const char broken[] = "broken";
  67. static char stext[256];
  68. @@ -284,6 +304,9 @@
  69. static Monitor *mons = NULL, *selmon = NULL;
  70. static Window root;
  71.  
  72. +Systray *trayicons;
  73. +Window traywin;
  74. +
  75. /* configuration, allows nested code to access above variables */
  76. #include "config.h"
  77.  
  78. @@ -533,6 +556,13 @@
  79. XClientMessageEvent *cme = &e->xclient;
  80. Client *c = wintoclient(cme->window);
  81.  
  82. + if(cme->window == traywin) {
  83. + if(cme->data.l[1] == XEMBED_EMBEDDED_NOTIFY){
  84. + systray_add(cme->data.l[2]);
  85. + systray_update();
  86. + }
  87. + }
  88. +
  89. if(!c)
  90. return;
  91. if(cme->message_type == netatom[NetWMState]) {
  92. @@ -644,7 +674,7 @@
  93. }
  94.  
  95. Monitor *
  96. -createmon(void) {
  97. +createmon(int primary) {
  98. Monitor *m;
  99.  
  100. if(!(m = (Monitor *)calloc(1, sizeof(Monitor))))
  101. @@ -657,16 +687,24 @@
  102. m->lt[0] = &layouts[0];
  103. m->lt[1] = &layouts[1 % LENGTH(layouts)];
  104. strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
  105. +
  106. + m->primary = primary;
  107. +
  108. return m;
  109. }
  110.  
  111. void
  112. destroynotify(XEvent *e) {
  113. Client *c;
  114. + Systray *s;
  115. XDestroyWindowEvent *ev = &e->xdestroywindow;
  116.  
  117. if((c = wintoclient(ev->window)))
  118. unmanage(c, True);
  119. + else if((s = systray_find(ev->window))){
  120. + systray_del(s);
  121. + systray_update();
  122. + }
  123. }
  124.  
  125. void
  126. @@ -743,6 +781,7 @@
  127. if(m == selmon) { /* status is only drawn on selected monitor */
  128. dc.w = TEXTW(stext);
  129. dc.x = m->ww - dc.w;
  130. + if(m->primary == 1) dc.x -= systray_get_width(); // subtract systray width
  131. if(dc.x < x) {
  132. dc.x = x;
  133. dc.w = m->ww - x;
  134. @@ -1321,6 +1360,7 @@
  135. if(ev->atom == netatom[NetWMWindowType])
  136. updatewindowtype(c);
  137. }
  138. +
  139. }
  140.  
  141. void
  142. @@ -1593,7 +1633,7 @@
  143. initfont(font);
  144. sw = DisplayWidth(dpy, screen);
  145. sh = DisplayHeight(dpy, screen);
  146. - bh = dc.h = dc.font.height + 2;
  147. + bh = dc.h = dc.font.height + 2;
  148. updategeom();
  149. /* init atoms */
  150. wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
  151. @@ -1605,6 +1645,7 @@
  152. netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
  153. netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
  154. netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
  155. + netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False);
  156. netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
  157. netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
  158. /* init cursors */
  159. @@ -1626,6 +1667,7 @@
  160. /* init bars */
  161. updatebars();
  162. updatestatus();
  163. + systray_acquire();
  164. /* EWMH support per view */
  165. XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
  166. PropModeReplace, (unsigned char *) netatom, NetLast);
  167. @@ -1870,12 +1912,13 @@
  168. XFree(info);
  169. nn = j;
  170. if(n <= nn) {
  171. - for(i = 0; i < (nn - n); i++) { /* new monitors available */
  172. + for(m = mons; m && m->next; m = m->next);
  173. + if(m) m->next = createmon(1);
  174. + else mons = createmon(1);
  175. + for(i = 1; i < (nn - n); i++) { /* new monitors available */
  176. for(m = mons; m && m->next; m = m->next);
  177. - if(m)
  178. - m->next = createmon();
  179. - else
  180. - mons = createmon();
  181. + if(m) m->next = createmon(0);
  182. + else mons = createmon(0);
  183. }
  184. for(i = 0, m = mons; i < nn && m; m = m->next, i++)
  185. if(i >= n
  186. @@ -1915,7 +1958,7 @@
  187. /* default monitor setup */
  188. {
  189. if(!mons)
  190. - mons = createmon();
  191. + mons = createmon(1);
  192. if(mons->mw != sw || mons->mh != sh) {
  193. dirty = True;
  194. mons->mw = mons->ww = sw;
  195. @@ -2126,6 +2169,155 @@
  196. pop(c);
  197. }
  198.  
  199. +Bool
  200. +systray_acquire(void) {
  201. + XSetWindowAttributes wattr;
  202. +
  203. + if(!systray_enable || traywin) return False;
  204. +
  205. + if(XGetSelectionOwner(dpy, netatom[NetSystemTray]) != None) {
  206. + fprintf(stderr, "Can't initialize system tray: owned by another process\n");
  207. + return False;
  208. + }
  209. +
  210. + // Init traywin window
  211. + wattr.event_mask = ButtonPressMask | ExposureMask;
  212. + wattr.override_redirect = True;
  213. + wattr.background_pixmap = ParentRelative;
  214. + wattr.background_pixel = dc.norm[ColBG];
  215. +
  216. + traywin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, dc.norm[ColBG]);
  217. +
  218. + XChangeWindowAttributes(dpy, traywin, CWEventMask | CWOverrideRedirect | CWBackPixel, &wattr);
  219. + XSelectInput(dpy, traywin, KeyPressMask | ButtonPressMask);
  220. +
  221. + XMapRaised(dpy, traywin);
  222. +
  223. + XSetSelectionOwner(dpy, netatom[NetSystemTray], traywin, CurrentTime);
  224. +
  225. + if(XGetSelectionOwner(dpy, netatom[NetSystemTray]) != traywin) {
  226. + systray_freeicons();
  227. + fprintf(stderr, "System tray: can't get systray manager\n");
  228. + return False;
  229. + }
  230. + XSync(dpy, False);
  231. +
  232. + return True;
  233. +}
  234. +
  235. +void
  236. +systray_add(Window win) {
  237. + Systray *s;
  238. +
  239. + if(!systray_enable) return;
  240. +
  241. + s = zcalloc(sizeof(Systray));
  242. + s->win = win;
  243. +
  244. + s->geo.height = bh;
  245. + s->geo.width = bh;
  246. +
  247. + XSelectInput(dpy, s->win, StructureNotifyMask | PropertyChangeMask| EnterWindowMask | FocusChangeMask);
  248. + XReparentWindow(dpy, s->win, traywin, 0, 0);
  249. +
  250. + // Attach
  251. + if(trayicons) trayicons->prev = s;
  252. +
  253. + s->next = trayicons;
  254. + trayicons = s;
  255. +
  256. + return;
  257. +}
  258. +
  259. +void
  260. +systray_del(Systray *s) {
  261. + Systray **ss;
  262. +
  263. + if(!systray_enable) return;
  264. +
  265. + for(ss = &trayicons; *ss && *ss != s; ss = &(*ss)->next);
  266. + *ss = s->next;
  267. +
  268. + IFREE(s);
  269. + return;
  270. +}
  271. +
  272. +void
  273. +systray_freeicons(void) {
  274. + Systray *i;
  275. +
  276. + if(!systray_enable) return;
  277. +
  278. + for(i = trayicons; i; i = i->next) {
  279. + XUnmapWindow(dpy, i->win);
  280. + XReparentWindow(dpy, i->win, ROOT, 0, 0);
  281. + IFREE(i);
  282. + }
  283. +
  284. + XSetSelectionOwner(dpy, netatom[NetSystemTray], None, CurrentTime);
  285. + XDestroyWindow(dpy, traywin);
  286. + XSync(dpy, 0);
  287. +
  288. + return;
  289. +}
  290. +
  291. +Systray*
  292. +systray_find(Window win) {
  293. + Systray *i;
  294. +
  295. + if(!systray_enable) return NULL;
  296. +
  297. + for(i = trayicons; i; i = i->next)
  298. + if(i->win == win) return i;
  299. +
  300. + return NULL;
  301. +}
  302. +
  303. +int
  304. +systray_get_width(void) {
  305. + int w = 0;
  306. + Systray *i;
  307. +
  308. + if(!systray_enable) return 0;
  309. +
  310. + for(i = trayicons; i; i = i->next)
  311. + w += i->geo.width + systray_spacing + 1;
  312. +
  313. + return w;
  314. +}
  315. +
  316. +void
  317. +systray_update(void) {
  318. + Systray *i;
  319. + Monitor *m;
  320. + int x = 1;
  321. + int pos = blw;
  322. +
  323. + if(!systray_enable) return;
  324. +
  325. + for(m = mons; m; m = m -> next){
  326. + if(m->primary == 1) pos = m -> ww;
  327. + }
  328. +
  329. + if(!trayicons) {
  330. + pos -= 1;
  331. + XMoveResizeWindow(dpy, traywin, pos, 0, 1, 1);
  332. + return;
  333. + }
  334. +
  335. + for(i = trayicons; i; i = i->next) {
  336. + XMapWindow(dpy, i->win);
  337. + XMoveResizeWindow(dpy, i->win, (i->geo.x = x), 0, i->geo.width, i->geo.height);
  338. +
  339. + x += i->geo.width + systray_spacing;
  340. + }
  341. +
  342. + pos -= x;
  343. + XMoveResizeWindow(dpy, traywin, pos, 0, x, bh);
  344. +
  345. + return;
  346. +}
  347. +
  348. int
  349. main(int argc, char *argv[]) {
  350. if(argc == 2 && !strcmp("-v", argv[1]))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement