Compare commits

...
10 Commits
Author SHA1 Message Date
Venelin Dechkov 129c6b712b VENE: basic keybinds 2026-02-25 12:10:04 +02:00
Julien AddéandHiltjo Posthuma 7175c4880b add -of and -ob arguments for outline colors options for multi-selection 2026-01-30 11:09:51 +01:00
Hiltjo Posthuma 8b48986f4c drw.c: drw_scm_free: call free inside
Because drw_scm_create() allocates it.
2025-09-29 18:47:16 +02:00
Hiltjo Posthuma 77f96d704b cleanup schemes and colors 2025-09-27 12:10:37 +02:00
Hiltjo Posthuma d893c63cdd bump version to 5.4 2025-08-09 14:33:40 +02:00
Adam PurkrtandHiltjo Posthuma b1e217b29a XUngrabKeyboard() instead of XUngrabKey()
XUngrabKey(), which is currently used in cleanup(), is not the right
counterpart to XGrabKeyboard(), which is used in grabkeyboard(),
called from main().

XUngrabKeyboard() is the function to use, as grabbing the whole
keyboard is different to grabbing individual keys.

With the current code the keyboard gets ungrabbed, as far as I can tell,
only by the final XCloseDisplay() in cleanup(), as the XUngrabKey()
there effectively does nothing.
2025-03-17 21:01:05 +01:00
Hiltjo Posthuma 86f0b5119e remove extra newline 2024-10-30 13:03:25 +01:00
Hiltjo Posthuma dd3d348ae8 Avoid unsigned integer underflow in drw_text()
Patch by Raymond Cole <rc@wolog.xyz>, thanks.
2024-10-30 13:02:57 +01:00
Hiltjo Posthuma 545031a076 util.c: output function might override errno and thus affect perror()
Original patch by Raymond Cole with some modifications, thanks!
2024-10-27 20:08:46 +01:00
Hiltjo Posthuma 475d8093cb drw.c: use the same pattern as ellipsis_width to check for infinite recursion 2024-07-14 11:43:01 +02:00
6 changed files with 89 additions and 28 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
# dmenu version
VERSION = 5.3
VERSION = 5.4
# paths
PREFIX = /usr/local
+10
View File
@@ -20,6 +20,10 @@ dmenu \- dynamic menu
.IR color ]
.RB [ \-sf
.IR color ]
.RB [ \-ob
.IR color ]
.RB [ \-of
.IR color ]
.RB [ \-w
.IR windowid ]
.P
@@ -75,6 +79,12 @@ defines the selected background color.
.BI \-sf " color"
defines the selected foreground color.
.TP
.BI \-ob " color"
defines the outline background color (for multiple selection).
.TP
.BI \-of " color"
defines the outline foreground color (for multiple selection).
.TP
.B \-v
prints version information to stdout, then exits.
.TP
+40 -15
View File
@@ -100,9 +100,9 @@ cleanup(void)
{
size_t i;
XUngrabKey(dpy, AnyKey, AnyModifier, root);
XUngrabKeyboard(dpy, CurrentTime);
for (i = 0; i < SchemeLast; i++)
free(scheme[i]);
drw_scm_free(drw, scheme[i], 2);
for (i = 0; items && items[i].text; ++i)
free(items[i].text);
free(items);
@@ -342,34 +342,38 @@ keypress(XKeyEvent *ev)
if (ev->state & ControlMask) {
switch(ksym) {
case XK_a: ksym = XK_Home; break;
case XK_h:
case XK_b: ksym = XK_Left; break;
case XK_c: ksym = XK_Escape; break;
case XK_d: ksym = XK_Delete; break;
case XK_e: ksym = XK_End; break;
case XK_l:
case XK_f: ksym = XK_Right; break;
case XK_g: ksym = XK_Escape; break;
case XK_h: ksym = XK_BackSpace; break;
// case XK_h: ksym = XK_BackSpace; break;
case XK_i: ksym = XK_Tab; break;
case XK_j: /* fallthrough */
case XK_J: /* fallthrough */
case XK_m: /* fallthrough */
case XK_M: ksym = XK_Return; ev->state &= ~ControlMask; break;
case XK_j: /* fallthrough */
case XK_J: /* fallthrough */
case XK_n: ksym = XK_Down; break;
case XK_k:
case XK_p: ksym = XK_Up; break;
case XK_k: /* delete right */
case XK_w:
// case XK_k: /* delete right */
text[cursor] = '\0';
match();
break;
case XK_u: /* delete left */
insert(NULL, 0 - cursor);
break;
case XK_w: /* delete word */
while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)]))
insert(NULL, nextrune(-1) - cursor);
while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)]))
insert(NULL, nextrune(-1) - cursor);
break;
// case XK_w: /* delete word */
// while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)]))
// insert(NULL, nextrune(-1) - cursor);
// while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)]))
// insert(NULL, nextrune(-1) - cursor);
// break;
case XK_y: /* paste selection */
case XK_Y:
XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
@@ -394,18 +398,36 @@ keypress(XKeyEvent *ev)
}
} else if (ev->state & Mod1Mask) {
switch(ksym) {
case XK_h:
case XK_b:
movewordedge(-1);
goto draw;
case XK_l:
case XK_f:
movewordedge(+1);
goto draw;
case XK_g: ksym = XK_Home; break;
case XK_G: ksym = XK_End; break;
case XK_h: ksym = XK_Up; break;
// case XK_h: ksym = XK_Up; break;
case XK_j: ksym = XK_Next; break;
case XK_k: ksym = XK_Prior; break;
case XK_l: ksym = XK_Down; break;
// case XK_l: ksym = XK_Down; break;
case XK_BackSpace:
while (cursor > 0 && strchr(worddelimiters, text[nextrune(-1)]))
insert(NULL, nextrune(-1) - cursor);
while (cursor > 0 && !strchr(worddelimiters, text[nextrune(-1)]))
insert(NULL, nextrune(-1) - cursor);
goto draw;
case XK_d: // forward delete word
while (text[cursor] != '\0' && strchr(worddelimiters, text[cursor])) { // delete space
cursor = nextrune(+1);
insert(NULL, nextrune(-1) - cursor);
}
while (text[cursor] != '\0' && !strchr(worddelimiters, text[cursor])) { // delete word
cursor = nextrune(+1);
insert(NULL, nextrune(-1) - cursor);
}
goto draw;
default:
return;
}
@@ -689,7 +711,6 @@ setup(void)
CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
XSetClassHint(dpy, win, &ch);
/* input methods */
if ((xim = XOpenIM(dpy, NULL, NULL, NULL)) == NULL)
die("XOpenIM failed: could not open input device");
@@ -756,6 +777,10 @@ main(int argc, char *argv[])
colors[SchemeSel][ColBg] = argv[++i];
else if (!strcmp(argv[i], "-sf")) /* selected foreground color */
colors[SchemeSel][ColFg] = argv[++i];
else if (!strcmp(argv[i], "-ob")) /* outline background color */
colors[SchemeOut][ColBg] = argv[++i];
else if (!strcmp(argv[i], "-of")) /* outline foreground color */
colors[SchemeOut][ColFg] = argv[++i];
else if (!strcmp(argv[i], "-w")) /* embedding window id */
embed = argv[++i];
else
+29 -6
View File
@@ -178,8 +178,7 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
die("error, cannot allocate color '%s'", clrname);
}
/* Wrapper to create color schemes. The caller has to call free(3) on the
* returned color scheme when done using it. */
/* Create color schemes. */
Clr *
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
{
@@ -187,7 +186,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
Clr *ret;
/* need at least two colors for a scheme */
if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(Clr))))
return NULL;
for (i = 0; i < clrcount; i++)
@@ -195,6 +194,30 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
return ret;
}
void
drw_clr_free(Drw *drw, Clr *c)
{
if (!drw || !c)
return;
/* c is typedef XftColor Clr */
XftColorFree(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen), c);
}
void
drw_scm_free(Drw *drw, Clr *scm, size_t clrcount)
{
size_t i;
if (!drw || !scm)
return;
for (i = 0; i < clrcount; i++)
drw_clr_free(drw, &scm[i]);
free(scm);
}
void
drw_setfontset(Drw *drw, Fnt *set)
{
@@ -248,6 +271,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
} else {
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
if (w < lpad)
return x + w;
d = XftDrawCreate(drw->dpy, drw->drawable,
DefaultVisual(drw->dpy, drw->screen),
DefaultColormap(drw->dpy, drw->screen));
@@ -258,10 +283,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
usedfont = drw->fonts;
if (!ellipsis_width && render)
ellipsis_width = drw_fontset_getwidth(drw, "...");
if (!invalid_width) {
invalid_width = -1; /* stop infinite recursion */
if (!invalid_width && render)
invalid_width = drw_fontset_getwidth(drw, invalid);
}
while (1) {
ew = ellipsis_len = utf8err = utf8charlen = utf8strlen = 0;
utf8str = text;
+2
View File
@@ -40,7 +40,9 @@ void drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned in
/* Colorscheme abstraction */
void drw_clr_create(Drw *drw, Clr *dest, const char *clrname);
void drw_clr_free(Drw *drw, Clr *c);
Clr *drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount);
void drw_scm_free(Drw *drw, Clr *scm, size_t clrcount);
/* Cursor abstraction */
Cur *drw_cur_create(Drw *drw, int shape);
+7 -6
View File
@@ -1,4 +1,5 @@
/* See LICENSE file for copyright and license details. */
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -10,17 +11,17 @@ void
die(const char *fmt, ...)
{
va_list ap;
int saved_errno;
saved_errno = errno;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
fputc(' ', stderr);
perror(NULL);
} else {
fputc('\n', stderr);
}
if (fmt[0] && fmt[strlen(fmt)-1] == ':')
fprintf(stderr, " %s", strerror(saved_errno));
fputc('\n', stderr);
exit(1);
}