diff options
| author | auric <104602845+ihateamongus@users.noreply.github.com> | 2025-09-11 10:13:20 -0500 |
|---|---|---|
| committer | auric <104602845+ihateamongus@users.noreply.github.com> | 2025-09-11 10:13:20 -0500 |
| commit | b9b34f91138c7b1cc2bc54571d1522c85cb581cd (patch) | |
| tree | 7a9c34c03c87e684079c8bd196bdf19cadebcbf3 /core/dmenu | |
| parent | 0408cb4803e0b2c82affb16e2eac8dfd73895343 (diff) | |
feat: add universal dmenu launcher
Diffstat (limited to 'core/dmenu')
| -rw-r--r-- | core/dmenu/dmenu.c | 128 |
1 files changed, 72 insertions, 56 deletions
diff --git a/core/dmenu/dmenu.c b/core/dmenu/dmenu.c index 54a14e2..28a0658 100644 --- a/core/dmenu/dmenu.c +++ b/core/dmenu/dmenu.c @@ -60,7 +60,9 @@ static Clr *scheme[SchemeLast]; #include "../accent.h" static ColorShm *accentshm; static char accentcol[8] = "#005577"; +static Clr accent[2]; static const double opacity = 0.85; +static const unsigned int border_width = 3; static void initaccent(void); static void updateaccent(void); @@ -128,8 +130,13 @@ cleanup(void) static void updateaccent(void) { - if (readaccent(&accentshm, accentcol)) + if (readaccent(&accentshm, accentcol)) { drw_clr_create(drw, &scheme[SchemeSel][ColBg], accentcol); + drw_clr_create(drw, &accent[ColFg], accentcol); + drw_clr_create(drw, &accent[ColBg], accentcol); + if (win) + XSetWindowBorder(dpy, win, accent[ColFg].pixel); + } } static void @@ -193,11 +200,15 @@ drawmenu(void) drw_rect(drw, x + curpos, 2, 2, bh - 4, 1, 0); } - if (lines > 0) { - /* draw vertical list */ - for (item = curr; item != next; item = item->right) - drawitem(item, x, y += bh, mw - x); - } else if (matches) { + if (lines > 0) { + /* draw vertical list */ + for (item = curr; item != next; item = item->right) { + y += bh; + drawitem(item, x, y, mw - x); + drw_setscheme(drw, accent); + drw_rect(drw, x, y + bh - 1, mw - x, 1, 1, 1); + } + } else if (matches) { /* draw horizontal list */ x += inputw; w = TEXTW("<"); @@ -675,67 +686,72 @@ setup(void) int a, di, n, area = 0; #endif /* init appearance */ - for (j = 0; j < SchemeLast; j++) - scheme[j] = drw_scm_create(drw, colors[j], 2); + for (j = 0; j < SchemeLast; j++) + scheme[j] = drw_scm_create(drw, colors[j], 2); + drw_clr_create(drw, &accent[ColFg], accentcol); + drw_clr_create(drw, &accent[ColBg], accentcol); clip = XInternAtom(dpy, "CLIPBOARD", False); utf8 = XInternAtom(dpy, "UTF8_STRING", False); - /* calculate menu geometry */ - bh = drw->fonts->h + 2; - lines = MAX(lines, 0); - mh = (lines + 1) * bh; + /* calculate menu geometry */ + bh = drw->fonts->h + 2; + lines = MAX(lines, 0); #ifdef XINERAMA - i = 0; - if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { - XGetInputFocus(dpy, &w, &di); - if (mon >= 0 && mon < n) - i = mon; - else if (w != root && w != PointerRoot && w != None) { - /* find top-level window containing current input focus */ - do { - if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws) - XFree(dws); - } while (w != root && w != pw); - /* find xinerama screen with which the window intersects most */ - if (XGetWindowAttributes(dpy, pw, &wa)) - for (j = 0; j < n; j++) - if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) { - area = a; - i = j; - } - } - /* no focused window is on screen, so use pointer location instead */ - if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) - for (i = 0; i < n; i++) - if (INTERSECT(x, y, 1, 1, info[i]) != 0) - break; - - x = info[i].x_org; - y = info[i].y_org + (topbar ? 0 : info[i].height - mh); - mw = info[i].width; - XFree(info); - } else + i = 0; + if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { + XGetInputFocus(dpy, &w, &di); + if (mon >= 0 && mon < n) + i = mon; + else if (w != root && w != PointerRoot && w != None) { + do { + if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws) + XFree(dws); + } while (w != root && w != pw); + if (XGetWindowAttributes(dpy, pw, &wa)) + for (j = 0; j < n; j++) + if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) { + area = a; + i = j; + } + } + if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) + for (i = 0; i < n; i++) + if (INTERSECT(x, y, 1, 1, info[i]) != 0) + break; + + mw = info[i].width / 2; + if (lines > info[i].height / bh - 1) + lines = info[i].height / bh - 1; + mh = (lines + 1) * bh; + x = info[i].x_org + (info[i].width - mw) / 2; + y = info[i].y_org + (info[i].height - mh) / 2; + XFree(info); + } else #endif - { - if (!XGetWindowAttributes(dpy, parentwin, &wa)) - die("could not get embedding window attributes: 0x%lx", - parentwin); - x = 0; - y = topbar ? 0 : wa.height - mh; - mw = wa.width; - } - promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; - inputw = mw / 3; /* input width: ~33% of monitor width */ - match(); + { + if (!XGetWindowAttributes(dpy, parentwin, &wa)) + die("could not get embedding window attributes: 0x%lx", + parentwin); + mw = wa.width / 2; + if (lines > wa.height / bh - 1) + lines = wa.height / bh - 1; + mh = (lines + 1) * bh; + x = (wa.width - mw) / 2; + y = (wa.height - mh) / 2; + } + promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; + inputw = mw - promptw; + match(); /* create menu window */ swa.override_redirect = True; swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - win = XCreateWindow(dpy, root, x, y, mw, mh, 0, - CopyFromParent, CopyFromParent, CopyFromParent, - CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); + swa.border_pixel = accent[ColFg].pixel; + win = XCreateWindow(dpy, root, x, y, mw, mh, border_width, + CopyFromParent, CopyFromParent, CopyFromParent, + CWOverrideRedirect | CWBackPixel | CWEventMask | CWBorderPixel, &swa); XSetClassHint(dpy, win, &ch); /* input methods */ |
