add -center- patch

This commit is contained in:
zcake 2021-02-19 11:03:58 +08:00
parent 29a9abaca9
commit a7251af7d5
11 changed files with 206 additions and 101 deletions

View File

@ -8,6 +8,8 @@ static const char *fonts[] = {
"monospace:size=10"
};
static const char *prompt = NULL; /* -p option; prompt to the left of input field */
static const char *symbol_1 = "<";
static const char *symbol_2 = ">";
static const char *colors[SchemeLast][2] = {
/* fg bg */
[SchemeNorm] = { "#bbbbbb", "#222222" },

11
config.def.h.rej Normal file
View File

@ -0,0 +1,11 @@
--- config.def.h
+++ config.def.h
@@ -2,6 +2,8 @@
/* Default settings; can be overriden by command line. */
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
+static int centered = 0; /* -c option; centers dmenu on screen */
+static int min_width = 500; /* minimum width when centered */
/* -fn option overrides fonts[0]; default X11 font or font set */
static const char *fonts[] = {
"monospace:size=10"

View File

@ -1,5 +1,7 @@
/* See LICENSE file for copyright and license details. */
/* Default settings; can be overriden by command line. */
static int centered = 0; /* -c option; centers dmenu on screen */
static int min_width = 500;
static const char *symbol_2 = "";
static const char *symbol_1 = "";
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */

BIN
dmenu

Binary file not shown.

View File

@ -22,6 +22,9 @@ dmenu appears at the bottom of the screen.
.B \-F
dmenu disable fuzzy search
.TP
.B \-c
dmenu appears centered on the screen.
.TP
.B \-f
dmenu grabs the keyboard before reading stdin if not reading from a tty. This
is faster, but will lock up X until stdin reaches end\-of\-file.

View File

@ -1,42 +1,13 @@
.TH DMENU 1 dmenu\-VERSION
.TH DMENU 1 dmenu \-VERSION
.SH NAME
dmenu \- dynamic menu
dmenu\- dynamic menu (zcake build)
.SH SYNOPSIS
.B dmenu
.RB [ \-bfivP ]
.RB [ \-l
.IR lines ]
.RB [ \-m
.IR monitor ]
.RB [ \-p
.IR prompt ]
.RB [ \-fn
.IR font ]
.RB [ \-nb
.IR color ]
.RB [ \-nf
.IR color ]
.RB [ \-sb
.IR color ]
.RB [ \-sf
.IR color ]
.RB [ \-nhb
.IR color ]
.RB [ \-nhf
.IR color ]
.RB [ \-shb
.IR color ]
.RB [ \-shf
.IR color ]
.RB [ \-w
.IR windowid ]
.P
.BR dmenu_run " ..."
.SH DESCRIPTION
.B dmenu
is a dynamic menu for X, which reads a list of newline\-separated items from
stdin. When the user selects an item and presses Return, their choice is printed
to stdout and dmenu terminates. Entering text will narrow the items to those
to stdout and dmenu (zcake build) terminates. Entering text will narrow the items to those
matching the tokens in the input.
.P
.B dmenu_run
@ -48,6 +19,9 @@ which lists programs in the user's $PATH and runs the result in their $SHELL.
.B \-b
dmenu appears at the bottom of the screen.
.TP
.B \-F
dmenu disable fuzzy search
.TP
.B \-f
dmenu grabs the keyboard before reading stdin if not reading from a tty. This
is faster, but will lock up X until stdin reaches end\-of\-file.
@ -59,52 +33,26 @@ dmenu matches menu items case insensitively.
dmenu will not directly display the keyboard input, but instead replace it with dots. All data from stdin will be ignored.
.TP
.BI \-l " lines"
dmenu lists items vertically, with the given number of lines.
dmenu (zcake build) lists items vertically, with the given number of lines.
.TP
.BI \-m " monitor"
dmenu is displayed on the monitor number supplied. Monitor numbers are starting
dmenu (zcake build) is displayed on the monitor number supplied. Monitor numbers are starting
from 0.
.TP
.BI \-p " prompt"
defines the prompt to be displayed to the left of the input field.
.TP
.BI \-fn " font"
defines the font or font set used.
.TP
.BI \-nb " color"
defines the normal background color.
.IR #RGB ,
.IR #RRGGBB ,
and X color names are supported.
.TP
.BI \-nf " color"
defines the normal foreground color.
.TP
.BI \-sb " color"
defines the selected background color.
.TP
.BI \-sf " color"
defines the selected foreground color.
.TP
.BI \-nhb " color"
defines the normal highlight background color.
.TP
.BI \-nhf " color"
defines the normal highlight foreground color.
.TP
.BI \-shb " color"
defines the selected highlight background color.
.TP
.BI \-shf " color"
defines the selected highlight foreground color.
.TP
.B \-v
prints version information to stdout, then exits.
.TP
.B \-n
runing dmenu with no item
.TP
.BI \-w " windowid"
embed into windowid.
.SH USAGE
dmenu is completely controlled by the keyboard. Items are selected using the
dmenu (zcake build) is completely controlled by the keyboard. Items are selected using the
arrow keys, page up, page down, home, and end.
.TP
.B Tab
@ -183,10 +131,10 @@ Delete line left
.B C\-w
Delete word left
.TP
.B C\-y
.B C\-V
Paste from primary X selection
.TP
.B C\-Y
.B C\-v
Paste from X clipboard
.TP
.B M\-b
@ -205,10 +153,10 @@ End
Up
.TP
.B M\-j
Page down
Down
.TP
.B M\-k
Page up
Up
.TP
.B M\-l
Down

41
dmenu.c
View File

@ -99,6 +99,15 @@ calcoffsets(void)
break;
}
static int
max_textw(void)
{
int len = 0;
for (struct item *item = items; item && item->text; item++)
len = MAX(TEXTW(item->text), len);
return len;
}
static void
cleanup(void)
{
@ -901,6 +910,7 @@ setup(void)
bh = drw->fonts->h + 2;
lines = MAX(lines, 0);
mh = (lines + 1) * bh;
promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
#ifdef XINERAMA
i = 0;
if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
@ -927,9 +937,16 @@ setup(void)
if (INTERSECT(x, y, 1, 1, info[i]))
break;
x = info[i].x_org;
y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
mw = info[i].width;
if (centered) {
mw = MIN(MAX(max_textw() + promptw, min_width), info[i].width);
x = info[i].x_org + ((info[i].width - mw) / 2);
y = info[i].y_org + ((info[i].height - mh) / 2);
} else {
x = info[i].x_org;
y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
mw = info[i].width;
}
XFree(info);
} else
#endif
@ -937,11 +954,17 @@ setup(void)
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;
if (centered) {
mw = MIN(MAX(max_textw() + promptw, min_width), wa.width);
x = (wa.width - mw) / 2;
y = (wa.height - mh) / 2;
} else {
x = 0;
y = topbar ? 0 : wa.height - mh;
mw = wa.width;
}
}
promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
inputw = MIN(inputw, mw/3);
match();
@ -1004,9 +1027,11 @@ main(int argc, char *argv[])
fuzzy = 0;
else if (!strcmp(argv[i], "-P")) /* is the input a password */
passwd = 1;
else if (!strcmp(argv[i], "-c")) /* centers dmenu on screen */
centered = 1;
else if (!strcmp(argv[i], "-n")) /* is the input a password */
no = 1;
else if (!strcmp(argv[i], "-s")) { /* case-sensitive item matching */
else if (!strcmp(argv[i], "-s")) { /* case-sensitive item matching */
fstrncmp = strncmp;
fstrstr = strstr;
} else if (i + 1 == argc)

View File

@ -89,7 +89,7 @@ calcoffsets(void)
if (lines > 0)
n = lines * bh;
else
n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">"));
n = mw - (promptw + inputw + TEXTW(symbol_1) + TEXTW(symbol_2));
/* calculate which items will begin the next page and previous page */
for (i = 0, next = curr; next; next = next->right)
if ((i += (lines > 0) ? bh : MIN(TEXTW(next->text), n)) > n)
@ -234,18 +234,18 @@ drawmenu(void)
} else if (matches) {
/* draw horizontal list */
x += inputw;
w = TEXTW("<");
w = TEXTW(symbol_1);
if (curr->left) {
drw_setscheme(drw, scheme[SchemeNorm]);
drw_text(drw, x, 0, w, bh, lrpad / 2, "<", 0);
drw_text(drw, x, 0, w, bh, lrpad / 2, symbol_1, 0);
}
x += w;
for (item = curr; item != next; item = item->right)
x = drawitem(item, x, 0, MIN(TEXTW(item->text), mw - x - TEXTW(">") - TEXTW(numbers)));
x = drawitem(item, x, 0, MIN(TEXTW(item->text), mw - x - TEXTW(symbol_2) - TEXTW(numbers)));
if (next) {
w = TEXTW(">");
w = TEXTW(symbol_2);
drw_setscheme(drw, scheme[SchemeNorm]);
drw_text(drw, mw - w - TEXTW(numbers), 0, w, bh, lrpad / 2, ">", 0);
drw_text(drw, mw - w - TEXTW(numbers), 0, w, bh, lrpad / 2, symbol_2, 0);
}
}
drw_setscheme(drw, scheme[SchemeNorm]);
@ -690,7 +690,7 @@ buttonpress(XEvent *e)
* add that to the input width */
if (ev->button == Button1 &&
((lines <= 0 && ev->x >= 0 && ev->x <= x + w +
((!prev || !curr->left) ? TEXTW("<") : 0)) ||
((!prev || !curr->left) ? TEXTW(symbol_1) : 0)) ||
(lines > 0 && ev->y >= y && ev->y <= y + h))) {
insert(NULL, -cursor);
drawmenu();
@ -741,7 +741,7 @@ buttonpress(XEvent *e)
} else if (matches) {
/* left-click on left arrow */
x += inputw;
w = TEXTW("<");
w = TEXTW(symbol_1);
if (prev && curr->left) {
if (ev->x >= x && ev->x <= x + w) {
sel = curr = prev;
@ -753,7 +753,7 @@ buttonpress(XEvent *e)
/* horizontal list: (ctrl)left-click on item */
for (item = curr; item != next; item = item->right) {
x += w;
w = MIN(TEXTW(item->text), mw - x - TEXTW(">"));
w = MIN(TEXTW(item->text), mw - x - TEXTW(symbol_2));
if (ev->x >= x && ev->x <= x + w) {
puts(item->text);
if (!(ev->state & ControlMask))
@ -767,7 +767,7 @@ buttonpress(XEvent *e)
}
}
/* left-click on right arrow */
w = TEXTW(">");
w = TEXTW(symbol_2);
x = mw - w;
if (next && ev->x >= x && ev->x <= x + w) {
sel = curr = next;

View File

@ -1,17 +1,11 @@
--- dmenu.c
+++ dmenu.c
@@ -165,11 +165,11 @@ drawmenu(void)
}
x += w;
for (item = curr; item != next; item = item->right)
- x = drawitem(item, x, 0, MIN(TEXTW(item->text), mw - x - TEXTW(">")));
+ x = drawitem(item, x, 0, MIN(TEXTW(item->text), mw - x - TEXTW(symbol_2)));
if (next) {
- w = TEXTW(">");
+ w = TEXTW(symbol_2);
drw_setscheme(drw, scheme[SchemeNorm]);
- drw_text(drw, mw - w, 0, w, bh, lrpad / 2, ">", 0);
+ drw_text(drw, mw - w, 0, w, bh, lrpad / 2, symbol_2, 0);
}
}
drw_map(drw, win, 0, 0, mw, mh);
@@ -732,6 +755,8 @@ main(int argc, char *argv[])
topbar = 0;
else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */
fast = 1;
+ else if (!strcmp(argv[i], "-c")) /* centers dmenu on screen */
+ centered = 1;
else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
fstrncmp = strncasecmp;
fstrstr = cistrstr;

BIN
dmenu.o

Binary file not shown.

View File

@ -0,0 +1,120 @@
From 8cd37e1ab9e7cb025224aeb3543f1a5be8bceb93 Mon Sep 17 00:00:00 2001
From: Nihal Jere <nihal@nihaljere.xyz>
Date: Sat, 11 Jan 2020 21:16:08 -0600
Subject: [PATCH] center patch now has adjustable minimum width
---
config.def.h | 2 ++
dmenu.1 | 3 +++
dmenu.c | 39 ++++++++++++++++++++++++++++++++-------
3 files changed, 37 insertions(+), 7 deletions(-)
diff --git a/config.def.h b/config.def.h
index 1edb647..88ef264 100644
--- a/config.def.h
+++ b/config.def.h
@@ -2,6 +2,8 @@
/* Default settings; can be overriden by command line. */
static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
+static int centered = 0; /* -c option; centers dmenu on screen */
+static int min_width = 500; /* minimum width when centered */
/* -fn option overrides fonts[0]; default X11 font or font set */
static const char *fonts[] = {
"monospace:size=10"
diff --git a/dmenu.1 b/dmenu.1
index 323f93c..c036baa 100644
--- a/dmenu.1
+++ b/dmenu.1
@@ -40,6 +40,9 @@ which lists programs in the user's $PATH and runs the result in their $SHELL.
.B \-b
dmenu appears at the bottom of the screen.
.TP
+.B \-c
+dmenu appears centered on the screen.
+.TP
.B \-f
dmenu grabs the keyboard before reading stdin if not reading from a tty. This
is faster, but will lock up X until stdin reaches end\-of\-file.
diff --git a/dmenu.c b/dmenu.c
index 65f25ce..041c7f8 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -89,6 +89,15 @@ calcoffsets(void)
break;
}
+static int
+max_textw(void)
+{
+ int len = 0;
+ for (struct item *item = items; item && item->text; item++)
+ len = MAX(TEXTW(item->text), len);
+ return len;
+}
+
static void
cleanup(void)
{
@@ -611,6 +620,7 @@ setup(void)
bh = drw->fonts->h + 2;
lines = MAX(lines, 0);
mh = (lines + 1) * bh;
+ promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
#ifdef XINERAMA
i = 0;
if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
@@ -637,9 +647,16 @@ setup(void)
if (INTERSECT(x, y, 1, 1, info[i]))
break;
- x = info[i].x_org;
- y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
- mw = info[i].width;
+ if (centered) {
+ mw = MIN(MAX(max_textw() + promptw, min_width), info[i].width);
+ x = info[i].x_org + ((info[i].width - mw) / 2);
+ y = info[i].y_org + ((info[i].height - mh) / 2);
+ } else {
+ x = info[i].x_org;
+ y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
+ mw = info[i].width;
+ }
+
XFree(info);
} else
#endif
@@ -647,11 +664,17 @@ setup(void)
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;
+
+ if (centered) {
+ mw = MIN(MAX(max_textw() + promptw, min_width), wa.width);
+ x = (wa.width - mw) / 2;
+ y = (wa.height - mh) / 2;
+ } else {
+ x = 0;
+ y = topbar ? 0 : wa.height - mh;
+ mw = wa.width;
+ }
}
- promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
inputw = MIN(inputw, mw/3);
match();
@@ -709,6 +732,8 @@ main(int argc, char *argv[])
topbar = 0;
else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */
fast = 1;
+ else if (!strcmp(argv[i], "-c")) /* centers dmenu on screen */
+ centered = 1;
else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
fstrncmp = strncasecmp;
fstrstr = cistrstr;
--
2.24.1