shod

mouse-based window manager that can tile windows inside floating containers
Log | Files | Refs | README | LICENSE

xnotif.c (3799B)


      1 #include "shod.h"
      2 
      3 /* create notification window */
      4 static void
      5 notifnew(Window win, int w, int h)
      6 {
      7 	struct Notification *notif;
      8 
      9 	notif = emalloc(sizeof(*notif));
     10 	*notif = (struct Notification){
     11 		.w = w + 2 * config.borderwidth,
     12 		.h = h + 2 * config.borderwidth,
     13 		.pix = None,
     14 		.obj.type = TYPE_NOTIFICATION,
     15 		.obj.win = win,
     16 	};
     17 	TAILQ_INSERT_TAIL(&wm.notifq, (struct Object *)notif, entry);
     18 	notif->frame = XCreateWindow(
     19 		dpy, root, 0, 0, 1, 1, 0,
     20 		depth, CopyFromParent, visual,
     21 		clientmask,
     22 		&(XSetWindowAttributes){
     23 			.event_mask = SubstructureNotifyMask | SubstructureRedirectMask,
     24 			.colormap = colormap
     25 		}
     26 	);
     27 	XReparentWindow(dpy, notif->obj.win, notif->frame, 0, 0);
     28 	XMapWindow(dpy, notif->obj.win);
     29 }
     30 
     31 /* decorate notification */
     32 void
     33 notifdecorate(struct Notification *n)
     34 {
     35 	/* (re)create pixmap */
     36 	if (n->pw != n->w || n->ph != n->h || n->pix == None) {
     37 		if (n->pix != None)
     38 			XFreePixmap(dpy, n->pix);
     39 		n->pix = XCreatePixmap(dpy, n->frame, n->w, n->h, depth);
     40 	}
     41 	n->pw = n->w;
     42 	n->ph = n->h;
     43 
     44 	drawborders(n->pix, n->w, n->h, FOCUSED);
     45 
     46 	drawcommit(n->pix, n->frame);
     47 }
     48 
     49 /* place notifications */
     50 void
     51 notifplace(void)
     52 {
     53 	struct Object *n;
     54 	struct Notification *notif;
     55 	int x, y, h;
     56 
     57 	h = 0;
     58 	TAILQ_FOREACH(n, &wm.notifq, entry) {
     59 		notif = (struct Notification *)n;
     60 		x = TAILQ_FIRST(&wm.monq)->wx;
     61 		y = TAILQ_FIRST(&wm.monq)->wy;
     62 		switch (config.notifgravity[0]) {
     63 		case 'N':
     64 			switch (config.notifgravity[1]) {
     65 			case 'W':
     66 				break;
     67 			case 'E':
     68 				x += TAILQ_FIRST(&wm.monq)->ww - notif->w;
     69 				break;
     70 			default:
     71 				x += (TAILQ_FIRST(&wm.monq)->ww - notif->w) / 2;
     72 				break;
     73 			}
     74 			break;
     75 		case 'S':
     76 			switch(config.notifgravity[1]) {
     77 			case 'W':
     78 				y += TAILQ_FIRST(&wm.monq)->wh - notif->h;
     79 				break;
     80 			case 'E':
     81 				x += TAILQ_FIRST(&wm.monq)->ww - notif->w;
     82 				y += TAILQ_FIRST(&wm.monq)->wh - notif->h;
     83 				break;
     84 			default:
     85 				x += (TAILQ_FIRST(&wm.monq)->ww - notif->w) / 2;
     86 				y += TAILQ_FIRST(&wm.monq)->wh - notif->h;
     87 				break;
     88 			}
     89 			break;
     90 		case 'W':
     91 			y += (TAILQ_FIRST(&wm.monq)->wh - notif->h) / 2;
     92 			break;
     93 		case 'C':
     94 			x += (TAILQ_FIRST(&wm.monq)->ww - notif->w) / 2;
     95 			y += (TAILQ_FIRST(&wm.monq)->wh - notif->h) / 2;
     96 			break;
     97 		case 'E':
     98 			x += TAILQ_FIRST(&wm.monq)->ww - notif->w;
     99 			y += (TAILQ_FIRST(&wm.monq)->wh - notif->h) / 2;
    100 			break;
    101 		default:
    102 			x += TAILQ_FIRST(&wm.monq)->ww - notif->w;
    103 			break;
    104 		}
    105 
    106 		if (config.notifgravity[0] == 'S')
    107 			y -= h;
    108 		else
    109 			y += h;
    110 		h += notif->h + config.notifgap + config.borderwidth * 2;
    111 
    112 		XMoveResizeWindow(dpy, notif->frame, x, y, notif->w, notif->h);
    113 		XMoveResizeWindow(dpy, notif->obj.win, config.borderwidth, config.borderwidth, notif->w - 2 * config.borderwidth, notif->h - 2 * config.borderwidth);
    114 		XMapWindow(dpy, notif->frame);
    115 		if (notif->pw != notif->w || notif->ph != notif->h) {
    116 			notifdecorate(notif);
    117 		}
    118 		winnotify(notif->obj.win, x + config.borderwidth, y + config.borderwidth, notif->w - 2 * config.borderwidth, notif->h - 2 * config.borderwidth);
    119 	}
    120 }
    121 
    122 /* add notification window into notification queue; and update notification placement */
    123 void
    124 managenotif(struct Tab *tab, struct Monitor *mon, int desk, Window win, Window leader, XRectangle rect, int state, int ignoreunmap)
    125 {
    126 	(void)tab;
    127 	(void)mon;
    128 	(void)desk;
    129 	(void)leader;
    130 	(void)state;
    131 	(void)ignoreunmap;
    132 	notifnew(win, rect.width, rect.height);
    133 	notifplace();
    134 }
    135 
    136 /* delete notification */
    137 int
    138 unmanagenotif(struct Object *obj, int dummy)
    139 {
    140 	struct Notification *notif;
    141 
    142 	(void)dummy;
    143 	notif = (struct Notification *)obj;
    144 	TAILQ_REMOVE(&wm.notifq, (struct Object *)notif, entry);
    145 	if (notif->pix != None)
    146 		XFreePixmap(dpy, notif->pix);
    147 	XReparentWindow(dpy, notif->obj.win, root, 0, 0);
    148 	XDestroyWindow(dpy, notif->frame);
    149 	free(notif);
    150 	notifplace();
    151 	return 0;
    152 }