Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --- dwm-6.0/dwm.c 2011-12-19 09:02:46.000000000 -0600
- +++ src/dwm-6.0/dwm.c 2011-12-31 18:41:07.804378632 -0600
- @@ -54,13 +54,17 @@
- #define HEIGHT(X) ((X)->h + 2 * (X)->bw)
- #define TAGMASK ((1 << LENGTH(tags)) - 1)
- #define TEXTW(X) (textnw(X, strlen(X)) + dc.font.height)
- +#define XEMBED_EMBEDDED_NOTIFY 0
- +#define IFREE(x) if(x) free(x)
- +#define zcalloc(size) calloc(1, (size))
- +#define ROOT RootWindow(dpy, DefaultScreen(dpy))
- /* enums */
- enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
- enum { ColBorder, ColFG, ColBG, ColLast }; /* color */
- enum { NetSupported, NetWMName, NetWMState,
- NetWMFullscreen, NetActiveWindow, NetWMWindowType,
- - NetWMWindowTypeDialog, NetLast }; /* EWMH atoms */
- + NetWMWindowTypeDialog,NetSystemTray, NetLast }; /* EWMH atoms */
- enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
- enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
- ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
- @@ -143,6 +147,7 @@
- Monitor *next;
- Window barwin;
- const Layout *lt[2];
- + int primary;
- };
- typedef struct {
- @@ -154,6 +159,13 @@
- int monitor;
- } Rule;
- +typedef struct Systray Systray;
- +struct Systray {
- + Window win;
- + XRectangle geo;
- + Systray *next, *prev;
- +};
- +
- /* function declarations */
- static void applyrules(Client *c);
- static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact);
- @@ -170,7 +182,7 @@
- static void configure(Client *c);
- static void configurenotify(XEvent *e);
- static void configurerequest(XEvent *e);
- -static Monitor *createmon(void);
- +static Monitor *createmon(int primary);
- static void destroynotify(XEvent *e);
- static void detach(Client *c);
- static void detachstack(Client *c);
- @@ -252,6 +264,14 @@
- static int xerrorstart(Display *dpy, XErrorEvent *ee);
- static void zoom(const Arg *arg);
- +static Bool systray_acquire(void);
- +static void systray_add(Window win);
- +static void systray_del(Systray *s);
- +static void systray_freeicons(void);
- +static Systray *systray_find(Window win);
- +static int systray_get_width(void);
- +static void systray_update(void);
- +
- /* variables */
- static const char broken[] = "broken";
- static char stext[256];
- @@ -284,6 +304,9 @@
- static Monitor *mons = NULL, *selmon = NULL;
- static Window root;
- +Systray *trayicons;
- +Window traywin;
- +
- /* configuration, allows nested code to access above variables */
- #include "config.h"
- @@ -533,6 +556,13 @@
- XClientMessageEvent *cme = &e->xclient;
- Client *c = wintoclient(cme->window);
- + if(cme->window == traywin) {
- + if(cme->data.l[1] == XEMBED_EMBEDDED_NOTIFY){
- + systray_add(cme->data.l[2]);
- + systray_update();
- + }
- + }
- +
- if(!c)
- return;
- if(cme->message_type == netatom[NetWMState]) {
- @@ -644,7 +674,7 @@
- }
- Monitor *
- -createmon(void) {
- +createmon(int primary) {
- Monitor *m;
- if(!(m = (Monitor *)calloc(1, sizeof(Monitor))))
- @@ -657,16 +687,24 @@
- m->lt[0] = &layouts[0];
- m->lt[1] = &layouts[1 % LENGTH(layouts)];
- strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
- +
- + m->primary = primary;
- +
- return m;
- }
- void
- destroynotify(XEvent *e) {
- Client *c;
- + Systray *s;
- XDestroyWindowEvent *ev = &e->xdestroywindow;
- if((c = wintoclient(ev->window)))
- unmanage(c, True);
- + else if((s = systray_find(ev->window))){
- + systray_del(s);
- + systray_update();
- + }
- }
- void
- @@ -743,6 +781,7 @@
- if(m == selmon) { /* status is only drawn on selected monitor */
- dc.w = TEXTW(stext);
- dc.x = m->ww - dc.w;
- + if(m->primary == 1) dc.x -= systray_get_width(); // subtract systray width
- if(dc.x < x) {
- dc.x = x;
- dc.w = m->ww - x;
- @@ -1321,6 +1360,7 @@
- if(ev->atom == netatom[NetWMWindowType])
- updatewindowtype(c);
- }
- +
- }
- void
- @@ -1593,7 +1633,7 @@
- initfont(font);
- sw = DisplayWidth(dpy, screen);
- sh = DisplayHeight(dpy, screen);
- - bh = dc.h = dc.font.height + 2;
- + bh = dc.h = dc.font.height + 2;
- updategeom();
- /* init atoms */
- wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
- @@ -1605,6 +1645,7 @@
- netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
- netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False);
- netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
- + netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False);
- netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
- netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
- /* init cursors */
- @@ -1626,6 +1667,7 @@
- /* init bars */
- updatebars();
- updatestatus();
- + systray_acquire();
- /* EWMH support per view */
- XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
- PropModeReplace, (unsigned char *) netatom, NetLast);
- @@ -1870,12 +1912,13 @@
- XFree(info);
- nn = j;
- if(n <= nn) {
- - for(i = 0; i < (nn - n); i++) { /* new monitors available */
- + for(m = mons; m && m->next; m = m->next);
- + if(m) m->next = createmon(1);
- + else mons = createmon(1);
- + for(i = 1; i < (nn - n); i++) { /* new monitors available */
- for(m = mons; m && m->next; m = m->next);
- - if(m)
- - m->next = createmon();
- - else
- - mons = createmon();
- + if(m) m->next = createmon(0);
- + else mons = createmon(0);
- }
- for(i = 0, m = mons; i < nn && m; m = m->next, i++)
- if(i >= n
- @@ -1915,7 +1958,7 @@
- /* default monitor setup */
- {
- if(!mons)
- - mons = createmon();
- + mons = createmon(1);
- if(mons->mw != sw || mons->mh != sh) {
- dirty = True;
- mons->mw = mons->ww = sw;
- @@ -2126,6 +2169,155 @@
- pop(c);
- }
- +Bool
- +systray_acquire(void) {
- + XSetWindowAttributes wattr;
- +
- + if(!systray_enable || traywin) return False;
- +
- + if(XGetSelectionOwner(dpy, netatom[NetSystemTray]) != None) {
- + fprintf(stderr, "Can't initialize system tray: owned by another process\n");
- + return False;
- + }
- +
- + // Init traywin window
- + wattr.event_mask = ButtonPressMask | ExposureMask;
- + wattr.override_redirect = True;
- + wattr.background_pixmap = ParentRelative;
- + wattr.background_pixel = dc.norm[ColBG];
- +
- + traywin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, dc.norm[ColBG]);
- +
- + XChangeWindowAttributes(dpy, traywin, CWEventMask | CWOverrideRedirect | CWBackPixel, &wattr);
- + XSelectInput(dpy, traywin, KeyPressMask | ButtonPressMask);
- +
- + XMapRaised(dpy, traywin);
- +
- + XSetSelectionOwner(dpy, netatom[NetSystemTray], traywin, CurrentTime);
- +
- + if(XGetSelectionOwner(dpy, netatom[NetSystemTray]) != traywin) {
- + systray_freeicons();
- + fprintf(stderr, "System tray: can't get systray manager\n");
- + return False;
- + }
- + XSync(dpy, False);
- +
- + return True;
- +}
- +
- +void
- +systray_add(Window win) {
- + Systray *s;
- +
- + if(!systray_enable) return;
- +
- + s = zcalloc(sizeof(Systray));
- + s->win = win;
- +
- + s->geo.height = bh;
- + s->geo.width = bh;
- +
- + XSelectInput(dpy, s->win, StructureNotifyMask | PropertyChangeMask| EnterWindowMask | FocusChangeMask);
- + XReparentWindow(dpy, s->win, traywin, 0, 0);
- +
- + // Attach
- + if(trayicons) trayicons->prev = s;
- +
- + s->next = trayicons;
- + trayicons = s;
- +
- + return;
- +}
- +
- +void
- +systray_del(Systray *s) {
- + Systray **ss;
- +
- + if(!systray_enable) return;
- +
- + for(ss = &trayicons; *ss && *ss != s; ss = &(*ss)->next);
- + *ss = s->next;
- +
- + IFREE(s);
- + return;
- +}
- +
- +void
- +systray_freeicons(void) {
- + Systray *i;
- +
- + if(!systray_enable) return;
- +
- + for(i = trayicons; i; i = i->next) {
- + XUnmapWindow(dpy, i->win);
- + XReparentWindow(dpy, i->win, ROOT, 0, 0);
- + IFREE(i);
- + }
- +
- + XSetSelectionOwner(dpy, netatom[NetSystemTray], None, CurrentTime);
- + XDestroyWindow(dpy, traywin);
- + XSync(dpy, 0);
- +
- + return;
- +}
- +
- +Systray*
- +systray_find(Window win) {
- + Systray *i;
- +
- + if(!systray_enable) return NULL;
- +
- + for(i = trayicons; i; i = i->next)
- + if(i->win == win) return i;
- +
- + return NULL;
- +}
- +
- +int
- +systray_get_width(void) {
- + int w = 0;
- + Systray *i;
- +
- + if(!systray_enable) return 0;
- +
- + for(i = trayicons; i; i = i->next)
- + w += i->geo.width + systray_spacing + 1;
- +
- + return w;
- +}
- +
- +void
- +systray_update(void) {
- + Systray *i;
- + Monitor *m;
- + int x = 1;
- + int pos = blw;
- +
- + if(!systray_enable) return;
- +
- + for(m = mons; m; m = m -> next){
- + if(m->primary == 1) pos = m -> ww;
- + }
- +
- + if(!trayicons) {
- + pos -= 1;
- + XMoveResizeWindow(dpy, traywin, pos, 0, 1, 1);
- + return;
- + }
- +
- + for(i = trayicons; i; i = i->next) {
- + XMapWindow(dpy, i->win);
- + XMoveResizeWindow(dpy, i->win, (i->geo.x = x), 0, i->geo.width, i->geo.height);
- +
- + x += i->geo.width + systray_spacing;
- + }
- +
- + pos -= x;
- + XMoveResizeWindow(dpy, traywin, pos, 0, x, bh);
- +
- + return;
- +}
- +
- int
- main(int argc, char *argv[]) {
- if(argc == 2 && !strcmp("-v", argv[1]))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement