xprompt.c (3041B)
1 #include "shod.h" 2 3 /* calculate position and size of prompt window and the size of its frame */ 4 static void 5 promptcalcgeom(int *x, int *y, int *w, int *h, int *fw, int *fh) 6 { 7 *w = min(*w, wm.selmon->ww - config.borderwidth * 2); 8 *h = min(*h, wm.selmon->wh - config.borderwidth); 9 *x = wm.selmon->wx + (wm.selmon->ww - *w) / 2 - config.borderwidth; 10 *y = wm.selmon->wy; 11 *fw = *w + config.borderwidth * 2; 12 *fh = *h + config.borderwidth; 13 } 14 15 /* check if event is related to the prompt or its frame */ 16 static Bool 17 promptvalidevent(Display *dpy, XEvent *ev, XPointer arg) 18 { 19 Window win; 20 21 (void)dpy; 22 win = *(Window *)arg; 23 switch(ev->type) { 24 case DestroyNotify: 25 if (ev->xdestroywindow.window == win) 26 return True; 27 break; 28 case UnmapNotify: 29 if (ev->xunmap.window == win) 30 return True; 31 break; 32 case ConfigureRequest: 33 if (ev->xconfigurerequest.window == win) 34 return True; 35 break; 36 case ButtonPress: 37 return True; 38 } 39 return False; 40 } 41 42 /* decorate prompt frame */ 43 static void 44 promptdecorate(Window frame, Pixmap *pix, int w, int h) 45 { 46 if (*pix != None) 47 XFreePixmap(dpy, *pix); 48 *pix = XCreatePixmap(dpy, frame, w, h, depth); 49 drawbackground(*pix, 0, 0, w, h, FOCUSED); 50 drawprompt(*pix, w, h); 51 drawcommit(*pix, frame); 52 } 53 54 /* map prompt, give it focus, wait for it to close, then revert focus to previously focused window */ 55 void 56 manageprompt(struct Tab *tab, struct Monitor *mon, int desk, Window win, Window leader, XRectangle rect, int state, int ignoreunmap) 57 { 58 Window frame; /* prompt frame */ 59 Pixmap pix; /* pixmap to draw the frame */ 60 XEvent ev; 61 int x, y, w, h, fw, fh; 62 63 (void)tab; 64 (void)mon; 65 (void)desk; 66 (void)leader; 67 (void)state; 68 (void)ignoreunmap; 69 w = rect.width; 70 h = rect.height; 71 promptcalcgeom(&x, &y, &w, &h, &fw, &fh); 72 frame = XCreateWindow(dpy, root, x, y, fw, fh, 0, depth, CopyFromParent, visual, clientmask, &clientswa); 73 pix = None; 74 XReparentWindow(dpy, win, frame, config.borderwidth, 0); 75 XMapWindow(dpy, win); 76 XMapWindow(dpy, frame); 77 XSetInputFocus(dpy, win, RevertToParent, CurrentTime); 78 promptdecorate(frame, &pix, fw, fh); 79 while (!XIfEvent(dpy, &ev, promptvalidevent, (XPointer)&win)) { 80 switch (ev.type) { 81 case DestroyNotify: 82 case UnmapNotify: 83 goto done; 84 break; 85 case ConfigureRequest: 86 w = ev.xconfigurerequest.width; 87 h = ev.xconfigurerequest.height; 88 promptcalcgeom(&x, &y, &w, &h, &fw, &fh); 89 XMoveResizeWindow(dpy, frame, x, y, fw, fh); 90 XMoveResizeWindow(dpy, win, config.borderwidth, 0, w, h); 91 promptdecorate(frame, &pix, fw, fh); 92 break; 93 case ButtonPress: 94 if (ev.xbutton.window != win && ev.xbutton.window != frame) 95 winclose(win); 96 XAllowEvents(dpy, ReplayPointer, CurrentTime); 97 break; 98 } 99 } 100 done: 101 XReparentWindow(dpy, win, root, 0, 0); 102 XDestroyWindow(dpy, frame); 103 if (wm.focused) { 104 tabfocus(wm.focused->selcol->selrow->seltab, 0); 105 } else { 106 tabfocus(NULL, 0); 107 } 108 } 109 110 int 111 unmanageprompt(struct Object *obj, int ignoreunmap) 112 { 113 (void)obj; 114 (void)ignoreunmap; 115 return 0; 116 }