diff options
| author | Bear <bear@bengtsson.win> | 2021-12-27 09:29:58 +0000 |
|---|---|---|
| committer | Bear <bear@bengtsson.win> | 2021-12-27 09:29:58 +0000 |
| commit | 69262b01ced79c2d776fab9b889926d1816a1e7a (patch) | |
| tree | f304cd6fa8734e83a7772d07dc9b484781565155 /patch/bar_systray.c | |
Added DWM
Diffstat (limited to 'patch/bar_systray.c')
| -rw-r--r-- | patch/bar_systray.c | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/patch/bar_systray.c b/patch/bar_systray.c new file mode 100644 index 0000000..67d1d2d --- /dev/null +++ b/patch/bar_systray.c @@ -0,0 +1,198 @@ +static Systray *systray = NULL; +static unsigned long systrayorientation = _NET_SYSTEM_TRAY_ORIENTATION_HORZ; + +int +width_systray(Bar *bar, BarArg *a) +{ + unsigned int w = 0; + Client *i; + if (!systray) + return 1; + if (showsystray) + for (i = systray->icons; i; w += i->w + systrayspacing, i = i->next); + return w ? w + lrpad - systrayspacing : 0; +} + +int +draw_systray(Bar *bar, BarArg *a) +{ + if (!showsystray) + return 0; + + XSetWindowAttributes wa; + XWindowChanges wc; + Client *i; + unsigned int w; + + if (!systray) { + /* init systray */ + if (!(systray = (Systray *)calloc(1, sizeof(Systray)))) + die("fatal: could not malloc() %u bytes\n", sizeof(Systray)); + + wa.override_redirect = True; + wa.event_mask = ButtonPressMask|ExposureMask; + wa.border_pixel = 0; + systray->h = MIN(a->h, drw->fonts->h); + #if BAR_ALPHA_PATCH + wa.background_pixel = 0; + wa.colormap = cmap; + systray->win = XCreateWindow(dpy, root, bar->bx + a->x + lrpad / 2, bar->by + a->y + (a->h - systray->h) / 2, MAX(a->w + 40, 1), systray->h, 0, depth, + InputOutput, visual, + CWOverrideRedirect|CWBorderPixel|CWBackPixel|CWColormap|CWEventMask, &wa); // CWBackPixmap + #else + wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; + systray->win = XCreateSimpleWindow(dpy, root, bar->bx + a->x + lrpad / 2, bar->by + a->y + (a->h - systray->h) / 2, MIN(a->w, 1), systray->h, 0, 0, scheme[SchemeNorm][ColBg].pixel); + XChangeWindowAttributes(dpy, systray->win, CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWEventMask, &wa); + #endif // BAR_ALPHA_PATCH + + XSelectInput(dpy, systray->win, SubstructureNotifyMask); + XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32, + PropModeReplace, (unsigned char *)&systrayorientation, 1); + #if BAR_ALPHA_PATCH + XChangeProperty(dpy, systray->win, netatom[NetSystemTrayVisual], XA_VISUALID, 32, + PropModeReplace, (unsigned char *)&visual->visualid, 1); + #endif // BAR_ALPHA_PATCH + XChangeProperty(dpy, systray->win, netatom[NetWMWindowType], XA_ATOM, 32, + PropModeReplace, (unsigned char *)&netatom[NetWMWindowTypeDock], 1); + XMapRaised(dpy, systray->win); + XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime); + if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) { + sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0); + XSync(dpy, False); + } else { + fprintf(stderr, "dwm: unable to obtain system tray.\n"); + free(systray); + systray = NULL; + return 0; + } + } + + systray->bar = bar; + + wc.stack_mode = Above; + wc.sibling = bar->win; + XConfigureWindow(dpy, systray->win, CWSibling|CWStackMode, &wc); + + drw_setscheme(drw, scheme[SchemeNorm]); + for (w = 0, i = systray->icons; i; i = i->next) { + #if BAR_ALPHA_PATCH + wa.background_pixel = 0; + #else + wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; + #endif // BAR_ALPHA_PATCH + XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa); + XMapRaised(dpy, i->win); + i->x = w; + XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h); + w += i->w; + if (i->next) + w += systrayspacing; + if (i->mon != bar->mon) + i->mon = bar->mon; + } + + XMoveResizeWindow(dpy, systray->win, bar->bx + a->x + lrpad / 2, (w ? bar->by + a->y + (a->h - systray->h) / 2: -bar->by - a->y), MAX(w, 1), systray->h); + return w; +} + +int +click_systray(Bar *bar, Arg *arg, BarArg *a) +{ + return -1; +} + +void +removesystrayicon(Client *i) +{ + Client **ii; + + if (!showsystray || !i) + return; + for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next); + if (ii) + *ii = i->next; + free(i); + drawbarwin(systray->bar); +} + +void +resizerequest(XEvent *e) +{ + XResizeRequestEvent *ev = &e->xresizerequest; + Client *i; + + if ((i = wintosystrayicon(ev->window))) { + updatesystrayicongeom(i, ev->width, ev->height); + drawbarwin(systray->bar); + } +} + +void +updatesystrayicongeom(Client *i, int w, int h) +{ + if (!systray) + return; + + int icon_height = systray->h; + if (i) { + i->h = icon_height; + if (w == h) + i->w = icon_height; + else if (h == icon_height) + i->w = w; + else + i->w = (int) ((float)icon_height * ((float)w / (float)h)); + applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False); + /* force icons into the systray dimensions if they don't want to */ + if (i->h > icon_height) { + if (i->w == i->h) + i->w = icon_height; + else + i->w = (int) ((float)icon_height * ((float)i->w / (float)i->h)); + i->h = icon_height; + } + if (i->w > 2 * icon_height) + i->w = icon_height; + } +} + +void +updatesystrayiconstate(Client *i, XPropertyEvent *ev) +{ + long flags; + int code = 0; + + if (!showsystray || !systray || !i || ev->atom != xatom[XembedInfo] || + !(flags = getatomprop(i, xatom[XembedInfo]))) + return; + + if (flags & XEMBED_MAPPED && !i->tags) { + i->tags = 1; + code = XEMBED_WINDOW_ACTIVATE; + XMapRaised(dpy, i->win); + setclientstate(i, NormalState); + } + else if (!(flags & XEMBED_MAPPED) && i->tags) { + i->tags = 0; + code = XEMBED_WINDOW_DEACTIVATE; + XUnmapWindow(dpy, i->win); + setclientstate(i, WithdrawnState); + } + else + return; + sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0, + systray->win, XEMBED_EMBEDDED_VERSION); +} + +Client * +wintosystrayicon(Window w) +{ + if (!systray) + return NULL; + Client *i = NULL; + if (!showsystray || !w) + return i; + for (i = systray->icons; i && i->win != w; i = i->next); + return i; +} + |
