dmenu for lunch applications in dwm
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

129 lines
2.8 KiB

  1. /* See LICENSE file for copyright and license details. */
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <X11/keysym.h>
  6. #ifdef XINERAMA
  7. #include <X11/extensions/Xinerama.h>
  8. #endif
  9. #include "dmenu.h"
  10. /* variables */
  11. char *prompt = NULL;
  12. char text[4096] = "";
  13. int promptw = 0;
  14. int screen;
  15. unsigned int numlockmask = 0;
  16. unsigned int mw, mh;
  17. unsigned long normcol[ColLast];
  18. unsigned long selcol[ColLast];
  19. Bool topbar = True;
  20. DC dc;
  21. Display *dpy;
  22. Window win, root;
  23. void
  24. grabkeyboard(void) {
  25. unsigned int len;
  26. for(len = 1000; len; len--) {
  27. if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime)
  28. == GrabSuccess)
  29. return;
  30. usleep(1000);
  31. }
  32. exit(EXIT_FAILURE);
  33. }
  34. void
  35. run(void) {
  36. XEvent ev;
  37. /* main event loop */
  38. XSync(dpy, False);
  39. while(!XNextEvent(dpy, &ev))
  40. switch(ev.type) {
  41. case KeyPress:
  42. kpress(&ev.xkey);
  43. break;
  44. case Expose:
  45. if(ev.xexpose.count == 0)
  46. drawbar();
  47. break;
  48. case VisibilityNotify:
  49. if(ev.xvisibility.state != VisibilityUnobscured)
  50. XRaiseWindow(dpy, win);
  51. break;
  52. }
  53. exit(EXIT_FAILURE);
  54. }
  55. void
  56. setup(unsigned int lines) {
  57. int i, j, x, y;
  58. #if XINERAMA
  59. int n;
  60. XineramaScreenInfo *info = NULL;
  61. #endif
  62. XModifierKeymap *modmap;
  63. XSetWindowAttributes wa;
  64. /* init modifier map */
  65. modmap = XGetModifierMapping(dpy);
  66. for(i = 0; i < 8; i++)
  67. for(j = 0; j < modmap->max_keypermod; j++) {
  68. if(modmap->modifiermap[i * modmap->max_keypermod + j]
  69. == XKeysymToKeycode(dpy, XK_Num_Lock))
  70. numlockmask = (1 << i);
  71. }
  72. XFreeModifiermap(modmap);
  73. dc.dpy = dpy;
  74. normcol[ColBG] = getcolor(&dc, normbgcolor);
  75. normcol[ColFG] = getcolor(&dc, normfgcolor);
  76. selcol[ColBG] = getcolor(&dc, selbgcolor);
  77. selcol[ColFG] = getcolor(&dc, selfgcolor);
  78. initfont(&dc, font);
  79. /* input window */
  80. wa.override_redirect = True;
  81. wa.background_pixmap = ParentRelative;
  82. wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
  83. /* input window geometry */
  84. mh = (dc.font.height + 2) * (lines + 1);
  85. #if XINERAMA
  86. if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) {
  87. i = 0;
  88. if(n > 1) {
  89. int di;
  90. unsigned int dui;
  91. Window dummy;
  92. if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui))
  93. for(i = 0; i < n; i++)
  94. if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))
  95. break;
  96. }
  97. x = info[i].x_org;
  98. y = topbar ? info[i].y_org : info[i].y_org + info[i].height - mh;
  99. mw = info[i].width;
  100. XFree(info);
  101. }
  102. else
  103. #endif
  104. {
  105. x = 0;
  106. y = topbar ? 0 : DisplayHeight(dpy, screen) - mh;
  107. mw = DisplayWidth(dpy, screen);
  108. }
  109. win = XCreateWindow(dpy, root, x, y, mw, mh, 0,
  110. DefaultDepth(dpy, screen), CopyFromParent,
  111. DefaultVisual(dpy, screen),
  112. CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
  113. setupdraw(&dc, win);
  114. if(prompt)
  115. promptw = MIN(textw(&dc, prompt), mw / 5);
  116. XMapRaised(dpy, win);
  117. }