fix(xdrawer,dwm,dmenu): remove top bar gap and eliminate softkey menu latency

This commit is contained in:
Luxferre
2026-10-21 10:11:11 +03:00
parent 8045929c87
commit 7b7ae1dcc5
9 changed files with 124 additions and 63 deletions
+61 -23
View File
@@ -1449,14 +1449,17 @@ ishold(KeySym keysym)
#define SOFTKEY_LEFT 1
#define SOFTKEY_RIGHT 2
#define SOFTKEY_CHORD_MS 200
#define SOFTKEY_MAX_HOLD_MS 480
#define SOFTKEY_CHORD_MS 30
#define SOFTKEY_CANCEL_WINDOW_MS 320
#define SOFTKEY_SUPPRESS_MS 500
static int softkey_pending = 0;
static long long softkey_first_ms = 0;
static long long softkey_deadline_ms = 0;
static long long softkey_suppress_until_ms = 0;
static int last_softkey_mask = 0;
static long long last_softkey_ms = 0;
static pid_t last_menu_pgid = 0;
static long long
dwm_now_ms(void)
@@ -1480,6 +1483,18 @@ write_softkey_suppress(long long until_ms)
}
}
static void
write_softkey_state(int mask, long long ms)
{
char buf[64];
int fd = open("/tmp/sxmo_softkey_state", O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
if (fd >= 0) {
int len = snprintf(buf, sizeof(buf), "%d %lld\n", mask, ms);
(void)write(fd, buf, len);
close(fd);
}
}
static long long
read_softkey_suppress(void)
{
@@ -1517,13 +1532,34 @@ is_right_softkey(KeySym ks, unsigned int keycode)
return ks == XF86XK_Back || ks == XF86XK_KbdLcdMenu2 || keycode == 166;
}
static pid_t
spawn_pgid(const Arg *arg)
{
pid_t pid = fork();
if (pid == 0) {
if (dpy)
close(ConnectionNumber(dpy));
setsid();
execvp(((char **)arg->v)[0], (char **)arg->v);
_exit(EXIT_SUCCESS);
}
return pid;
}
static void
trigger_xdrawer_chord(long long now)
{
const Arg xdrawercmd = { .v = (const char*[]){ "xdrawer", NULL } };
if (last_menu_pgid > 0) {
kill(-last_menu_pgid, SIGKILL);
last_menu_pgid = 0;
}
softkey_pending = 0;
softkey_first_ms = 0;
softkey_deadline_ms = 0;
last_softkey_mask = 0;
last_softkey_ms = 0;
write_softkey_state(0, 0);
write_softkey_suppress(now + SOFTKEY_SUPPRESS_MS);
XUngrabKeyboard(dpy, CurrentTime);
XFlush(dpy);
@@ -1541,10 +1577,10 @@ flush_pending_softkey(void)
XFlush(dpy);
if (pending == SOFTKEY_LEFT) {
const Arg syscmd = { .v = (const char*[]){ "sxmo_appmenu.sh", "sys", NULL } };
spawn(&syscmd);
last_menu_pgid = spawn_pgid(&syscmd);
} else if (pending == SOFTKEY_RIGHT) {
const Arg ctxcmd = { .v = (const char*[]){ "sxmo_appmenu.sh", NULL } };
spawn(&ctxcmd);
last_menu_pgid = spawn_pgid(&ctxcmd);
}
}
@@ -1567,6 +1603,9 @@ keypress(XEvent *e)
softkey_pending = 0;
softkey_first_ms = 0;
softkey_deadline_ms = 0;
last_softkey_mask = 0;
last_softkey_ms = 0;
write_softkey_state(0, 0);
write_softkey_suppress(dwm_now_ms() + SOFTKEY_SUPPRESS_MS);
XUngrabKeyboard(dpy, CurrentTime);
XFlush(dpy);
@@ -1583,16 +1622,25 @@ keypress(XEvent *e)
XFlush(dpy);
return;
}
int which = 0;
if (is_left_softkey(keysym, ev->keycode))
softkey_pending |= SOFTKEY_LEFT;
which |= SOFTKEY_LEFT;
if (is_right_softkey(keysym, ev->keycode))
softkey_pending |= SOFTKEY_RIGHT;
softkey_pending |= query_softkeys_down();
if (softkey_pending == (SOFTKEY_LEFT | SOFTKEY_RIGHT)) {
which |= SOFTKEY_RIGHT;
int combined = softkey_pending | which | query_softkeys_down();
if (last_softkey_mask != 0 && (now - last_softkey_ms) <= SOFTKEY_CANCEL_WINDOW_MS)
combined |= last_softkey_mask;
if (combined == (SOFTKEY_LEFT | SOFTKEY_RIGHT)) {
trigger_xdrawer_chord(now);
} else if (softkey_deadline_ms == 0) {
softkey_first_ms = now;
softkey_deadline_ms = now + SOFTKEY_CHORD_MS;
} else {
softkey_pending = which;
last_softkey_mask = which;
last_softkey_ms = now;
write_softkey_state(which, now);
if (softkey_deadline_ms == 0) {
softkey_first_ms = now;
softkey_deadline_ms = now + SOFTKEY_CHORD_MS;
}
}
return;
}
@@ -1640,11 +1688,6 @@ keyrelease(XEvent *e)
markreleased(keysym);
if (is_left_softkey(keysym, ev->keycode) || is_right_softkey(keysym, ev->keycode)) {
if (softkey_pending != 0 && softkey_pending != (SOFTKEY_LEFT | SOFTKEY_RIGHT)) {
long long grace = dwm_now_ms() + 65;
if (grace > softkey_deadline_ms)
softkey_deadline_ms = grace;
}
return;
}
@@ -2100,13 +2143,8 @@ run(void)
}
long long rem = softkey_deadline_ms - now;
if (rem <= 0) {
if (hw_down != 0 && (now - softkey_first_ms) < SOFTKEY_MAX_HOLD_MS) {
softkey_deadline_ms = now + 25;
timeout_ms = 25;
} else {
flush_pending_softkey();
continue;
}
flush_pending_softkey();
continue;
} else {
timeout_ms = (int)rem;
}