summaryrefslogtreecommitdiff
path: root/dmenu/dmenu.c
diff options
context:
space:
mode:
authorauric <104602845+ihateamongus@users.noreply.github.com>2025-09-07 18:12:31 -0500
committerauric <104602845+ihateamongus@users.noreply.github.com>2025-09-07 18:12:31 -0500
commit65edb9b634e62fdf10abd7fff4794e4501202567 (patch)
treef664235a8de0fe7999055af2ec556ac6fdfc1c77 /dmenu/dmenu.c
parentb59b8b8e5d16af7f0daccb280a4991e3fe428e41 (diff)
Fix duplicate scratchpad and accent declarations
Diffstat (limited to 'dmenu/dmenu.c')
-rw-r--r--dmenu/dmenu.c163
1 files changed, 124 insertions, 39 deletions
diff --git a/dmenu/dmenu.c b/dmenu/dmenu.c
index fd49549..066d20f 100644
--- a/dmenu/dmenu.c
+++ b/dmenu/dmenu.c
@@ -7,6 +7,11 @@
#include <strings.h>
#include <time.h>
#include <unistd.h>
+#include <stdint.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/select.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
@@ -52,6 +57,20 @@ static XIC xic;
static Drw *drw;
static Clr *scheme[SchemeLast];
+#define SHMNAME "/breathing_color_shm"
+typedef struct {
+uint32_t seq;
+char color[8];
+} ColorShm;
+static ColorShm *accentshm;
+static char accentcol[8] = "#005577";
+static const double opacity = 0.85;
+
+static void initaccent(void);
+static void updateaccent(void);
+static int openaccent(void);
+static void setopacity(Window w, double opacity);
+
#include "config.h"
static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
@@ -111,6 +130,47 @@ cleanup(void)
XCloseDisplay(dpy);
}
+static int
+openaccent(void)
+{
+ int fd;
+ if (accentshm)
+ return 1;
+ if ((fd = shm_open(SHMNAME, O_RDONLY, 0)) < 0)
+ return 0;
+ accentshm = mmap(NULL, sizeof(ColorShm), PROT_READ, MAP_SHARED, fd, 0);
+ close(fd);
+ if (accentshm == MAP_FAILED) {
+ accentshm = NULL;
+ return 0;
+ }
+ return 1;
+}
+
+static void
+updateaccent(void)
+{
+ uint32_t s1, s2;
+ char tmp[8];
+
+ if (!accentshm && !openaccent())
+ return;
+ do {
+ s1 = accentshm->seq;
+ memcpy(tmp, accentshm->color, 8);
+ s2 = accentshm->seq;
+ } while (s1 != s2);
+ if (tmp[0] != '#')
+ return;
+ memcpy(accentcol, tmp, 8);
+ drw_clr_create(drw, &scheme[SchemeSel][ColBg], accentcol);
+}
+
+static void
+initaccent(void)
+{
+ updateaccent();
+}
static char *
cistrstr(const char *h, const char *n)
{
@@ -192,6 +252,15 @@ drawmenu(void)
}
static void
+setopacity(Window w, double op)
+{
+ unsigned long val = op * 0xffffffff;
+ XChangeProperty(dpy, w, XInternAtom(dpy, "_NET_WM_WINDOW_OPACITY", False),
+ XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char *)&val, 1);
+}
+
+static void
grabfocus(void)
{
struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 };
@@ -575,39 +644,53 @@ readstdin(void)
static void
run(void)
{
- XEvent ev;
-
- while (!XNextEvent(dpy, &ev)) {
- if (XFilterEvent(&ev, win))
- continue;
- switch(ev.type) {
- case DestroyNotify:
- if (ev.xdestroywindow.window != win)
- break;
- cleanup();
- exit(1);
- case Expose:
- if (ev.xexpose.count == 0)
- drw_map(drw, win, 0, 0, mw, mh);
- break;
- case FocusIn:
- /* regrab focus from parent window */
- if (ev.xfocus.window != win)
- grabfocus();
- break;
- case KeyPress:
- keypress(&ev.xkey);
- break;
- case SelectionNotify:
- if (ev.xselection.property == utf8)
- paste();
- break;
- case VisibilityNotify:
- if (ev.xvisibility.state != VisibilityUnobscured)
- XRaiseWindow(dpy, win);
- break;
- }
- }
+ XEvent ev;
+ int xfd;
+ fd_set fds;
+ struct timeval tv;
+
+ xfd = ConnectionNumber(dpy);
+ for (;;) {
+ FD_ZERO(&fds);
+ FD_SET(xfd, &fds);
+ tv.tv_sec = 0;
+ tv.tv_usec = 50000;
+ if (select(xfd + 1, &fds, NULL, NULL, &tv) > 0) {
+ while (XPending(dpy)) {
+ XNextEvent(dpy, &ev);
+ if (XFilterEvent(&ev, win))
+ continue;
+ switch (ev.type) {
+ case DestroyNotify:
+ if (ev.xdestroywindow.window != win)
+ break;
+ cleanup();
+ exit(1);
+ case Expose:
+ if (ev.xexpose.count == 0)
+ drw_map(drw, win, 0, 0, mw, mh);
+ break;
+ case FocusIn:
+ if (ev.xfocus.window != win)
+ grabfocus();
+ break;
+ case KeyPress:
+ keypress(&ev.xkey);
+ break;
+ case SelectionNotify:
+ if (ev.xselection.property == utf8)
+ paste();
+ break;
+ case VisibilityNotify:
+ if (ev.xvisibility.state != VisibilityUnobscured)
+ XRaiseWindow(dpy, win);
+ break;
+ }
+ }
+ }
+ updateaccent();
+ drawmenu();
+ }
}
static void
@@ -696,10 +779,11 @@ setup(void)
xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
XNClientWindow, win, XNFocusWindow, win, NULL);
- XMapRaised(dpy, win);
- if (embed) {
- XReparentWindow(dpy, win, parentwin, x, y);
- XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask);
+ XMapRaised(dpy, win);
+ setopacity(win, opacity);
+ if (embed) {
+ XReparentWindow(dpy, win, parentwin, x, y);
+ XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask);
if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) {
for (i = 0; i < du && dws[i] != win; ++i)
XSelectInput(dpy, dws[i], FocusChangeMask);
@@ -707,8 +791,9 @@ setup(void)
}
grabfocus();
}
- drw_resize(drw, mw, mh);
- drawmenu();
+ drw_resize(drw, mw, mh);
+ initaccent();
+ drawmenu();
}
static void