Skip to content

Commit

Permalink
revert -r remotion; fix mouse control
Browse files Browse the repository at this point in the history
  • Loading branch information
phillbush committed May 9, 2021
1 parent 9e8388d commit 97960d7
Show file tree
Hide file tree
Showing 2 changed files with 220 additions and 106 deletions.
41 changes: 40 additions & 1 deletion pmenu.1
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
pmenu \- pie menu utility for X
.SH SYNOPSIS
.B pmenu
.RB [ \-tw ]
.RB [ \-ptw ]
.RB [ \-m
.IR modifier ]
.RB [ \-r
.IR button ]
.SH DESCRIPTION
.B pmenu
is a pie menu for X,
Expand All @@ -14,6 +18,41 @@ The pie menu contains one slice for each item.
.PP
The options are as follows:
.TP
.BI "\-m " modifier
Use the button click specified by the
.B \-r
option with the given modifier number to spawn the pie menu.
For example, if calling pmenu with the
.B -r 3 -m 4
options,
the pie menu will be displayed when clicking any window with the right mouse button
and the Mod4 modifier (usually the Super key).
this option only makes sense when
.B \-r
is used.
.TP
.B \-p
When
.B \-r
is used, pass the click to the root window,
for the window manage to use it, for example.
This option only makes sense when
.B \-r
is used.
.TP
.B \-r
When this option is used,
.B pmenu
listens to button presses on the root window,
and shows the pie menu when the button (a number between 1 and 3) is pressed on the root window.
This option makes
.B menu
run continuously,
so it should be run in background on a X startup file (like
.BR "~/.xinitrc" ,
.BR "~/.xprofile" ,
etc).
.TP
.B \-t
Draw a triangle on the border of slices that spawn a submenu.
.TP
Expand Down
285 changes: 180 additions & 105 deletions pmenu.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,20 @@ static struct Monitor mon;
static struct Pie pie;

/* flags */
static int rflag = 0; /* wheter to run in root mode */
static int pflag = 0; /* whether to pass click to root window */
static int tflag = 0; /* whether to draw triangle for submenus */
static int wflag = 0; /* whether to disable pointer warping */
static unsigned int button; /* button to trigger pmenu in root mode */
static unsigned int modifier; /* modifier to trigger pmenu */

#include "config.h"

/* show usage */
static void
usage(void)
{
(void)fprintf(stderr, "usage: pmenu [-w]\n");
(void)fprintf(stderr, "usage: pmenu [-ptw] [-m modifier] [-r button]\n");
exit(1);
}

Expand Down Expand Up @@ -83,8 +87,46 @@ getoptions(int *argc, char ***argv)
{
int ch;

while ((ch = getopt(*argc, *argv, "tw")) != -1) {
while ((ch = getopt(*argc, *argv, "m:pr:tw")) != -1) {
switch (ch) {
case 'm':
switch (*optarg) {
default:
case '1':
modifier = Mod1Mask;
break;
case '2':
modifier = Mod2Mask;
break;
case '3':
modifier = Mod3Mask;
break;
case '4':
modifier = Mod4Mask;
break;
case '5':
modifier = Mod5Mask;
break;
}
break;
case 'p':
pflag = 1;
break;
case 'r':
rflag = 1;
switch (*optarg) {
case '1':
button = Button1;
break;
case '2':
button = Button2;
break;
default:
case '3':
button = Button3;
break;
}
break;
case 't':
tflag = 1;
break;
Expand Down Expand Up @@ -1140,118 +1182,147 @@ run(struct Menu *rootmenu)
struct Slice *slice = NULL;
KeySym ksym;
XEvent ev;

getmonitor();
prevmenu = NULL;
currmenu = rootmenu;
grabpointer();
grabkeyboard();
placemenu(currmenu);
prevmenu = mapmenu(currmenu, prevmenu);
while (!XNextEvent(dpy, &ev)) {
switch (ev.type) {
case Expose:
if (ev.xexpose.count == 0)
int mapped = 0;

if (!rflag) {
getmonitor();
prevmenu = NULL;
currmenu = rootmenu;
grabpointer();
grabkeyboard();
placemenu(currmenu);
prevmenu = mapmenu(currmenu, prevmenu);
XWarpPointer(dpy, None, currmenu->win, 0, 0, 0, 0, pie.radius, pie.radius);
}
do {
while (!XNextEvent(dpy, &ev)) {
if (rflag && !mapped && ev.type == ButtonPress) {
if (ev.xbutton.state == modifier || ev.xbutton.subwindow == None) {
if (pflag && ev.xbutton.state == 0)
XAllowEvents(dpy, ReplayPointer, CurrentTime);
mapped = 1;
getmonitor();
prevmenu = NULL;
currmenu = rootmenu;
grabpointer();
grabkeyboard();
placemenu(currmenu);
prevmenu = mapmenu(currmenu, prevmenu);
XWarpPointer(dpy, None, currmenu->win, 0, 0, 0, 0, pie.radius, pie.radius);
} else {
XAllowEvents(dpy, ReplayPointer, CurrentTime);
}
continue;
}
switch (ev.type) {
case Expose:
if (ev.xexpose.count == 0)
copymenu(currmenu);
break;
case EnterNotify:
menu = getmenu(currmenu, ev.xcrossing.window);
if (menu == NULL)
break;
prevmenu = mapmenu(currmenu, prevmenu);
copymenu(currmenu);
break;
case EnterNotify:
menu = getmenu(currmenu, ev.xcrossing.window);
if (menu == NULL)
break;
prevmenu = mapmenu(currmenu, prevmenu);
copymenu(currmenu);
break;
case LeaveNotify:
menu = getmenu(currmenu, ev.xcrossing.window);
if (menu == NULL)
case LeaveNotify:
menu = getmenu(currmenu, ev.xcrossing.window);
if (menu == NULL)
break;
if (menu != rootmenu && menu == currmenu) {
currmenu = currmenu->parent;
prevmenu = mapmenu(currmenu, prevmenu);
}
currmenu->selected = NULL;
copymenu(currmenu);
break;
if (menu != rootmenu && menu == currmenu) {
currmenu = currmenu->parent;
case MotionNotify:
menu = getmenu(currmenu, ev.xbutton.window);
slice = getslice(menu, ev.xbutton.x, ev.xbutton.y);
if (menu == NULL)
break;
else if (slice == NULL)
menu->selected = NULL;
else
menu->selected = slice;
copymenu(currmenu);
break;
case ButtonRelease:
if (ev.xbutton.button != Button1 && ev.xbutton.button != Button3)
break;
menu = getmenu(currmenu, ev.xbutton.window);
slice = getslice(menu, ev.xbutton.x, ev.xbutton.y);
if (menu == NULL || slice == NULL)
break;
selectslice:
if (slice->submenu) {
currmenu = slice->submenu;
} else {
printf("%s\n", slice->output);
fflush(stdout);
goto done;
}
prevmenu = mapmenu(currmenu, prevmenu);
}
currmenu->selected = NULL;
copymenu(currmenu);
break;
case MotionNotify:
menu = getmenu(currmenu, ev.xbutton.window);
slice = getslice(menu, ev.xbutton.x, ev.xbutton.y);
if (menu == NULL)
currmenu->selected = NULL;
copymenu(currmenu);
if (!wflag)
XWarpPointer(dpy, None, currmenu->win, 0, 0, 0, 0, pie.radius, pie.radius);
break;
else if (slice == NULL)
menu->selected = NULL;
else
menu->selected = slice;
copymenu(currmenu);
break;
case ButtonRelease:
menu = getmenu(currmenu, ev.xbutton.window);
slice = getslice(menu, ev.xbutton.x, ev.xbutton.y);
if (menu == NULL || slice == NULL)
case ButtonPress:
if (ev.xbutton.button != Button1 && ev.xbutton.button != Button3)
break;
menu = getmenu(currmenu, ev.xbutton.window);
slice = getslice(menu, ev.xbutton.x, ev.xbutton.y);
if (menu == NULL || slice == NULL)
goto done;
break;
selectslice:
if (slice->submenu) {
currmenu = slice->submenu;
} else {
printf("%s\n", slice->output);
fflush(stdout);
goto done;
}
prevmenu = mapmenu(currmenu, prevmenu);
currmenu->selected = NULL;
copymenu(currmenu);
if (!wflag)
XWarpPointer(dpy, None, currmenu->win, 0, 0, 0, 0, pie.radius, pie.radius);
break;
case ButtonPress:
menu = getmenu(currmenu, ev.xbutton.window);
slice = getslice(menu, ev.xbutton.x, ev.xbutton.y);
if (menu == NULL || slice == NULL)
goto done;
break;
case KeyPress:
ksym = XkbKeycodeToKeysym(dpy, ev.xkey.keycode, 0, 0);

/* esc closes pmenu when current menu is the root menu */
if (ksym == XK_Escape && currmenu->parent == NULL)
goto done;

/* Shift-Tab = ISO_Left_Tab */
if (ksym == XK_Tab && (ev.xkey.state & ShiftMask))
ksym = XK_ISO_Left_Tab;

/* cycle through menu */
slice = NULL;
if (ksym == XK_Tab) {
slice = slicecycle(currmenu, 1);
} else if (ksym == XK_ISO_Left_Tab) {
slice = slicecycle(currmenu, 0);
} else if ((ksym == XK_Return) &&
currmenu->selected != NULL) {
slice = currmenu->selected;
goto selectslice;
} else if ((ksym == XK_Escape) &&
currmenu->parent != NULL) {
slice = currmenu->parent->selected;
currmenu = currmenu->parent;
prevmenu = mapmenu(currmenu, prevmenu);
} else
case KeyPress:
ksym = XkbKeycodeToKeysym(dpy, ev.xkey.keycode, 0, 0);

/* esc closes pmenu when current menu is the root menu */
if (ksym == XK_Escape && currmenu->parent == NULL)
goto done;

/* Shift-Tab = ISO_Left_Tab */
if (ksym == XK_Tab && (ev.xkey.state & ShiftMask))
ksym = XK_ISO_Left_Tab;

/* cycle through menu */
slice = NULL;
if (ksym == XK_Tab) {
slice = slicecycle(currmenu, 1);
} else if (ksym == XK_ISO_Left_Tab) {
slice = slicecycle(currmenu, 0);
} else if ((ksym == XK_Return) &&
currmenu->selected != NULL) {
slice = currmenu->selected;
goto selectslice;
} else if ((ksym == XK_Escape) &&
currmenu->parent != NULL) {
slice = currmenu->parent->selected;
currmenu = currmenu->parent;
prevmenu = mapmenu(currmenu, prevmenu);
} else
break;
currmenu->selected = slice;
copymenu(currmenu);
break;
currmenu->selected = slice;
copymenu(currmenu);
break;
case ConfigureNotify:
menu = getmenu(currmenu, ev.xconfigure.window);
if (menu == NULL)
case ConfigureNotify:
menu = getmenu(currmenu, ev.xconfigure.window);
if (menu == NULL)
break;
menu->x = ev.xconfigure.x;
menu->y = ev.xconfigure.y;
break;
menu->x = ev.xconfigure.x;
menu->y = ev.xconfigure.y;
break;
}
}
}
done:
unmapmenu(currmenu);
ungrab();
XFlush(dpy);
done:
mapped = 0;
unmapmenu(currmenu);
ungrab();
XFlush(dpy);
} while (rflag);
}

/* recursivelly free pixmaps and destroy windows */
Expand Down Expand Up @@ -1343,6 +1414,10 @@ main(int argc, char *argv[])
initdc();
initpie();

/* if running in root mode, get button presses from root window */
if (rflag)
XGrabButton(dpy, button, AnyModifier, rootwin, False, ButtonPressMask, GrabModeSync, GrabModeSync, None, None);

/* generate menus and set them up */
rootmenu = parsestdin();
if (rootmenu == NULL)
Expand Down

0 comments on commit 97960d7

Please sign in to comment.