Make xmenu wait for another process to ungrab

Xmenu didn't wait for another process to ungrab the poiter or keyboard,
ending up in erroneous behavior.  Now it waits.
This commit is contained in:
phillbush 2020-05-19 09:17:06 -03:00
parent c49dad285c
commit 85003546a2

55
xmenu.c
View File

@ -77,13 +77,14 @@ static void getcolor(const char *s, XftColor *color);
static void getresources(void); static void getresources(void);
static void setupdc(void); static void setupdc(void);
static void setupgeom(void); static void setupgeom(void);
static void setupgrab(void);
static struct Item *allocitem(const char *label, const char *output); static struct Item *allocitem(const char *label, const char *output);
static struct Menu *allocmenu(struct Menu *parent, struct Item *list, unsigned level); static struct Menu *allocmenu(struct Menu *parent, struct Item *list, unsigned level);
static void getmenuitem(Window win, int y, struct Menu **menu_ret, struct Item **item_ret); static void getmenuitem(Window win, int y, struct Menu **menu_ret, struct Item **item_ret);
static void drawmenu(void); static void drawmenu(void);
static void calcscreengeom(void); static void calcscreengeom(void);
static void calcmenu(struct Menu *menu); static void calcmenu(struct Menu *menu);
static void grabpointer(void);
static void grabkeyboard(void);
static void setcurrmenu(struct Menu *currmenu_new); static void setcurrmenu(struct Menu *currmenu_new);
static void parsestdin(void); static void parsestdin(void);
static void run(void); static void run(void);
@ -156,8 +157,10 @@ main(int argc, char *argv[])
calcmenu(rootmenu); calcmenu(rootmenu);
/* grab mouse and keyboard */ /* grab mouse and keyboard */
if (override_redirect) if (override_redirect) {
setupgrab(); grabpointer();
grabkeyboard();
}
/* map root menu */ /* map root menu */
currmenu = rootmenu; currmenu = rootmenu;
@ -256,19 +259,6 @@ setupgeom(void)
geom.separator = separatorsize; geom.separator = separatorsize;
} }
/* grab pointer */
static void
setupgrab(void)
{
if (XGrabPointer(dpy, rootwin, True, ButtonPressMask,
GrabModeAsync, GrabModeAsync, None,
None, CurrentTime) != GrabSuccess)
errx(1, "cannot grab pointer");
if (XGrabKeyboard(dpy, rootwin, True, GrabModeAsync,
GrabModeAsync, CurrentTime) != GrabSuccess)
errx(1, "cannot grab keyboard");
}
/* allocate an item */ /* allocate an item */
static struct Item * static struct Item *
allocitem(const char *label, const char *output) allocitem(const char *label, const char *output)
@ -523,6 +513,39 @@ calcmenu(struct Menu *menu)
} }
} }
/* try to grab pointer, we may have to wait for another process to ungrab */
static void
grabpointer(void)
{
struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 };
int i;
for (i = 0; i < 1000; i++) {
if (XGrabPointer(dpy, rootwin, True, ButtonPressMask,
GrabModeAsync, GrabModeAsync, None,
None, CurrentTime) == GrabSuccess)
return;
nanosleep(&ts, NULL);
}
errx(1, "cannot grab keyboard");
}
/* try to grab keyboard, we may have to wait for another process to ungrab */
static void
grabkeyboard(void)
{
struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 };
int i;
for (i = 0; i < 1000; i++) {
if (XGrabKeyboard(dpy, rootwin, True, GrabModeAsync,
GrabModeAsync, CurrentTime) == GrabSuccess)
return;
nanosleep(&ts, NULL);
}
errx(1, "cannot grab keyboard");
}
/* get menu and item of given window and position */ /* get menu and item of given window and position */
static void static void
getmenuitem(Window win, int y, getmenuitem(Window win, int y,