Xinqi Bao's Git
projects
/
dmenu.git
/ commitdiff
summary
|
log
|
commit
|
diff
|
tree
raw
|
patch
|
inline
| side by side (parent:
a97f550
)
add embedding support with -w option
author
Quentin Rameau <
[email protected]
>
Sat, 8 Oct 2016 12:08:28 +0000
(14:08 +0200)
committer
Hiltjo Posthuma <
[email protected]
>
Fri, 14 Oct 2016 13:26:35 +0000
(15:26 +0200)
dmenu.1
patch
|
blob
|
history
dmenu.c
patch
|
blob
|
history
diff --git
a/dmenu.1
b/dmenu.1
index
8bbd79d
..
9eab758
100644
(file)
--- a/
dmenu.1
+++ b/
dmenu.1
@@
-20,6
+20,8
@@
dmenu \- dynamic menu
.IR color ]
.RB [ \-sf
.IR color ]
.IR color ]
.RB [ \-sf
.IR color ]
+.RB [ \-w
+.IR windowid ]
.P
.BR dmenu_run " ..."
.SH DESCRIPTION
.P
.BR dmenu_run " ..."
.SH DESCRIPTION
@@
-75,6
+77,9
@@
defines the selected foreground color.
.TP
.B \-v
prints version information to stdout, then exits.
.TP
.B \-v
prints version information to stdout, then exits.
+.TP
+.BI \-w " windowid"
+embed into windowid.
.SH USAGE
dmenu is completely controlled by the keyboard. Items are selected using the
arrow keys, page up, page down, home, and end.
.SH USAGE
dmenu is completely controlled by the keyboard. Items are selected using the
arrow keys, page up, page down, home, and end.
diff --git
a/dmenu.c
b/dmenu.c
index
ff74369
..
9278e91
100644
(file)
--- a/
dmenu.c
+++ b/
dmenu.c
@@
-34,8
+34,8
@@
struct item {
};
static char text[BUFSIZ] = "";
};
static char text[BUFSIZ] = "";
+static char *embed;
static int bh, mw, mh;
static int bh, mw, mh;
-static int sw, sh; /* X display screen geometry width, height */
static int inputw = 0, promptw;
static int lrpad; /* sum of left and right padding */
static size_t cursor;
static int inputw = 0, promptw;
static int lrpad; /* sum of left and right padding */
static size_t cursor;
@@
-46,7
+46,7
@@
static int mon = -1, screen;
static Atom clip, utf8;
static Display *dpy;
static Atom clip, utf8;
static Display *dpy;
-static Window root, win;
+static Window root,
parentwin,
win;
static XIC xic;
static Drw *drw;
static XIC xic;
static Drw *drw;
@@
-174,12
+174,31
@@
drawmenu(void)
drw_map(drw, win, 0, 0, mw, mh);
}
drw_map(drw, win, 0, 0, mw, mh);
}
+static void
+grabfocus(void)
+{
+ struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 };
+ Window focuswin;
+ int i, revertwin;
+
+ for (i = 0; i < 100; ++i) {
+ XGetInputFocus(dpy, &focuswin, &revertwin);
+ if (focuswin == win)
+ return;
+ XSetInputFocus(dpy, win, RevertToParent, CurrentTime);
+ nanosleep(&ts, NULL);
+ }
+ die("cannot grab focus");
+}
+
static void
grabkeyboard(void)
{
struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 };
int i;
static void
grabkeyboard(void)
{
struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 };
int i;
+ if (embed)
+ return;
/* try to grab keyboard, we may have to wait for another process to ungrab */
for (i = 0; i < 1000; i++) {
if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync,
/* try to grab keyboard, we may have to wait for another process to ungrab */
for (i = 0; i < 1000; i++) {
if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync,
@@
-497,6
+516,11
@@
run(void)
if (ev.xexpose.count == 0)
drw_map(drw, win, 0, 0, mw, mh);
break;
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 KeyPress:
keypress(&ev.xkey);
break;
@@
-539,7
+563,7
@@
setup(void)
lines = MAX(lines, 0);
mh = (lines + 1) * bh;
#ifdef XINERAMA
lines = MAX(lines, 0);
mh = (lines + 1) * bh;
#ifdef XINERAMA
- if ((info = XineramaQueryScreens(dpy, &n))) {
+ if (
parentwin == root &&
(info = XineramaQueryScreens(dpy, &n))) {
XGetInputFocus(dpy, &w, &di);
if (mon >= 0 && mon < n)
i = mon;
XGetInputFocus(dpy, &w, &di);
if (mon >= 0 && mon < n)
i = mon;
@@
-570,9
+594,12
@@
setup(void)
} else
#endif
{
} else
#endif
{
+ if (!XGetWindowAttributes(dpy, parentwin, &wa))
+ die("could not get embedding window attributes: 0x%lx",
+ parentwin);
x = 0;
x = 0;
- y = topbar ? 0 :
sh
- mh;
- mw =
sw
;
+ y = topbar ? 0 :
wa.height
- mh;
+ mw =
wa.width
;
}
promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
inputw = MIN(inputw, mw/3);
}
promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
inputw = MIN(inputw, mw/3);
@@
-582,9
+609,8
@@
setup(void)
swa.override_redirect = True;
swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
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,
- DefaultDepth(dpy, screen), CopyFromParent,
- DefaultVisual(dpy, screen),
+ win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
+ CopyFromParent, CopyFromParent, CopyFromParent,
CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
/* open input methods */
CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);
/* open input methods */
@@
-593,6
+619,15
@@
setup(void)
XNClientWindow, win, XNFocusWindow, win, NULL);
XMapRaised(dpy, win);
XNClientWindow, win, XNFocusWindow, win, NULL);
XMapRaised(dpy, win);
+ if (embed) {
+ XSelectInput(dpy, parentwin, FocusChangeMask);
+ if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) {
+ for (i = 0; i < du && dws[i] != win; ++i)
+ XSelectInput(dpy, dws[i], FocusChangeMask);
+ XFree(dws);
+ }
+ grabfocus();
+ }
drw_resize(drw, mw, mh);
drawmenu();
}
drw_resize(drw, mw, mh);
drawmenu();
}
@@
-601,13
+636,14
@@
static void
usage(void)
{
fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
usage(void)
{
fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
- " [-nb color] [-nf color] [-sb color] [-sf color]\n", stderr);
+ " [-nb color] [-nf color] [-sb color] [-sf color]
[-w windowid]
\n", stderr);
exit(1);
}
int
main(int argc, char *argv[])
{
exit(1);
}
int
main(int argc, char *argv[])
{
+ XWindowAttributes wa;
int i, fast = 0;
for (i = 1; i < argc; i++)
int i, fast = 0;
for (i = 1; i < argc; i++)
@@
-641,6
+677,8
@@
main(int argc, char *argv[])
colors[SchemeSel][ColBg] = argv[++i];
else if (!strcmp(argv[i], "-sf")) /* selected foreground color */
colors[SchemeSel][ColFg] = argv[++i];
colors[SchemeSel][ColBg] = argv[++i];
else if (!strcmp(argv[i], "-sf")) /* selected foreground color */
colors[SchemeSel][ColFg] = argv[++i];
+ else if (!strcmp(argv[i], "-w")) /* embedding window id */
+ embed = argv[++i];
else
usage();
else
usage();
@@
-650,9
+688,12
@@
main(int argc, char *argv[])
die("cannot open display");
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
die("cannot open display");
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
- sw = DisplayWidth(dpy, screen);
- sh = DisplayHeight(dpy, screen);
- drw = drw_create(dpy, screen, root, sw, sh);
+ if (!embed || !(parentwin = strtol(embed, NULL, 0)))
+ parentwin = root;
+ if (!XGetWindowAttributes(dpy, parentwin, &wa))
+ die("could not get embedding window attributes: 0x%lx",
+ parentwin);
+ drw = drw_create(dpy, screen, root, wa.width, wa.height);
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
die("no fonts could be loaded.");
lrpad = drw->fonts->h;
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
die("no fonts could be loaded.");
lrpad = drw->fonts->h;