diff options
author | oga | 2008-01-14 15:21:10 +0000 |
---|---|---|
committer | oga | 2008-01-14 15:21:10 +0000 |
commit | 923c9f8936be6a656e3f9b6607c69a820b411330 (patch) | |
tree | a6af6b773f95cc8f4d00ade3cc49f812cb873cdd /grab.c | |
parent | 13d8a3a4a43bbca611050d5fd8dca3871225b8fb (diff) | |
download | cwm-923c9f8936be6a656e3f9b6607c69a820b411330.tar.gz |
Rewrite most of grab_menu in grab.c (it was partly 9wm code).
This should work functionally the same, with a few simplifications.
Changes:
- we don't care if you're holding another button when you release the
menu key if you don't want to select anything, move off the menu.
- remove the hysteresis from the menu selection (before you had to move
more than three pixels onto a new menu entry before it selected it)
- simplify a lot of the selection code
- kill dead code.
- do what the XXX comment said and cache the screensize (i may tweak
this later).
As far as I can tell, the only code remaining from 9wm is the list of
fonts in calmwm.c. Others appear to concur.
ok marc@, looked over and tested by a few others. Reminders from okan@.
Diffstat (limited to 'grab.c')
-rw-r--r-- | grab.c | 336 |
1 files changed, 84 insertions, 252 deletions
@@ -15,14 +15,14 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $Id: grab.c,v 1.6 2008/01/11 16:06:44 oga Exp $ + * $Id: grab.c,v 1.7 2008/01/14 15:21:10 oga Exp $ */ #include "headers.h" #include "calmwm.h" -int _sweepcalc(struct client_ctx *, int, int, int, int); -int _nobuttons(XButtonEvent *); +static int _sweepcalc(struct client_ctx *, int, int, int, int); +static int menu_calc_entry(int, int, int, int, int); #define ADJUST_HEIGHT(cc, dy) ((cc->geom.height - cc->geom.min_dy)/ dy) #define ADJUST_WIDTH(cc, dx) ((cc->geom.width - cc->geom.min_dx)/ dx) @@ -144,205 +144,113 @@ grab_drag(struct client_ctx *cc) /* NOTREACHED */ } -/* - * Adapted from 9wm. - */ - -/* XXX - this REALLY needs to be cleaned up. */ - #define MenuMask (ButtonMask|ButtonMotionMask|ExposureMask) #define MenuGrabMask (ButtonMask|ButtonMotionMask|StructureNotifyMask) #define AllButtonMask (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask) -#ifdef notyet -struct client_ctx * -grab_menu_getcc(struct menu_q *menuq, int off) -{ - int where = 0; - struct menu *mi; - - TAILQ_FOREACH(mi, menuq, entry) - if (off == where++) - return mi->ctx; - return (NULL); -} -#endif - void * grab_menu(XButtonEvent *e, struct menu_q *menuq) { struct screen_ctx *sc; struct menu *mi; - XEvent ev; - int i, n, cur = 0, old, wide, high, status, drawn, warp; - int x, y, dx, dy, xmax, ymax; - int tx, ty; + XEvent event; struct fontdesc *font = DefaultFont; + int x, y, width, height, tothigh, i, no, entry, prev; + int fx, fy; + + no = i = width = 0; if ((sc = screen_fromroot(e->root)) == NULL || e->window == sc->menuwin) return (NULL); - dx = 0; - i = 0; TAILQ_FOREACH(mi, menuq, entry) { - wide = font_width(font, mi->text, strlen(mi->text)) + 4; - if (wide > dx) - dx = wide; - if (mi->lasthit) - cur = i; - i++; + i = font_width(font, mi->text, strlen(mi->text)) + 4; + if (i > width) + width = i; + no++; } - n = i; - - wide = dx; - high = font_ascent(font) + font_descent(font) + 1; - dy = n*high; - x = e->x - wide/2; - y = e->y - cur*high - high/2; - warp = 0; - /* XXX - cache these in sc. */ - xmax = DisplayWidth(X_Dpy, sc->which); - ymax = DisplayHeight(X_Dpy, sc->which); - if (x < 0) { - e->x -= x; - x = 0; - warp++; + if (!sc->maxinitialised) { + sc->xmax = DisplayWidth(X_Dpy, sc->which); + sc->ymax = DisplayHeight(X_Dpy, sc->which); } - if (x+wide >= xmax) { - e->x -= x+wide-xmax; - x = xmax-wide; - warp++; - } - if (y < 0) { - e->y -= y; + + height = font_ascent(font) + font_descent(font) + 1; + tothigh = height * no; + + x = e->x - width/2; + y = e->y - height/2; + + /* does it fit on the screen? */ + if (x < 0) + x = 0; + else if (x+width >= sc->xmax) + x = sc->xmax - width; + + if (y < 0) y = 0; - warp++; - } - if (y+dy >= ymax) { - e->y -= y+dy-ymax; - y = ymax-dy; - warp++; - } - if (warp) - xu_ptr_setpos(e->root, e->x, e->y); + else if (y+tothigh >= sc->ymax) + y = sc->ymax - tothigh; - XMoveResizeWindow(X_Dpy, sc->menuwin, x, y, dx, dy); + xu_ptr_setpos(e->root, x + width/2, y + height/2); + + XMoveResizeWindow(X_Dpy, sc->menuwin, x, y, width, tothigh); XSelectInput(X_Dpy, sc->menuwin, MenuMask); XMapRaised(X_Dpy, sc->menuwin); - status = xu_ptr_grab(sc->menuwin, MenuGrabMask, Cursor_select); - if (status < 0) { + + if (xu_ptr_grab(sc->menuwin, MenuGrabMask, Cursor_select) < 0) { XUnmapWindow(X_Dpy, sc->menuwin); return (NULL); } - drawn = 0; - -#ifdef notyet - if (e->button == Button1) { - struct client_ctx *cc; - cc = grab_menu_getcc(menuq, cur); - if (cc != NULL) { - client_unhide(cc); - XRaiseWindow(X_Dpy, sc->menuwin); - } - } -#endif + + entry = prev = -1; for (;;) { - XMaskEvent(X_Dpy, MenuMask, &ev); - switch (ev.type) { - default: - warnx("menuhit: unknown ev.type %d\n", ev.type); - break; - case ButtonPress: + XMaskEvent(X_Dpy, MenuMask, &event); + switch (event.type) { + case Expose: + XClearWindow(X_Dpy, sc->menuwin); + i = 0; + TAILQ_FOREACH(mi, menuq, entry) { + fx = (width - font_width(font, mi->text, + strlen(mi->text)))/2; + fy = height*i + font_ascent(font) + 1; + font_draw(font, mi->text, strlen(mi->text), + sc->menuwin, fx, fy); + i++; + } + if (entry != -1) + XFillRectangle(X_Dpy, sc->menuwin, sc->hlgc, + 0, entry*height, width, height); + case MotionNotify: + prev = entry; + entry = menu_calc_entry(event.xbutton.x, + event.xbutton.y, width, height, no); + if (prev != -1) + XFillRectangle(X_Dpy, sc->menuwin, sc->hlgc, + 0, height*prev, width, height); + if (entry != -1) { + xu_ptr_regrab(MenuGrabMask, Cursor_select); + XFillRectangle(X_Dpy, sc->menuwin, sc->hlgc, + 0, height*entry, width, height); + } else + xu_ptr_regrab(MenuGrabMask, Cursor_default); break; case ButtonRelease: - if (ev.xbutton.button != e->button) + if (event.xbutton.button != e->button) break; - x = ev.xbutton.x; - y = ev.xbutton.y; - i = y/high; - if (cur >= 0 && y >= cur*high-3 && y < (cur+1)*high+3) - i = cur; - if (x < 0 || x > wide || y < -3) - i = -1; - else if (i < 0 || i >= n) - i = -1; -/* else */ -/* m->lasthit = i; */ - if (!_nobuttons(&ev.xbutton)) - i = -1; - - /* XXX */ - /* ungrab(&ev.xbutton); */ + entry = menu_calc_entry(event.xbutton.x, + event.xbutton.y, width, height, no); xu_ptr_ungrab(); XUnmapWindow(X_Dpy, sc->menuwin); - n = 0; + + i = 0; TAILQ_FOREACH(mi, menuq, entry) - if (i == n++) + if (entry == i++) break; - return (mi); - case MotionNotify: - if (!drawn) - break; - x = ev.xbutton.x; - y = ev.xbutton.y; - old = cur; - cur = y/high; - if (old >= 0 && y >= old*high-3 && y < (old+1)*high+3) - cur = old; - if (x < 0 || x > wide || y < -3) - cur = -1; - else if (cur < 0 || cur >= n) - cur = -1; - if (cur == old) - break; - if (old >= 0 && old < n) { -#ifdef notyet - if (e->button == Button1) { - struct client_ctx *cc; - cc = grab_menu_getcc(menuq, old); - if (cc != NULL) - client_hide(cc); - } -#endif - XFillRectangle(X_Dpy, sc->menuwin, - sc->hlgc, 0, old*high, wide, high); - } - if (cur >= 0 && cur < n) { -#ifdef notyet - if (e->button == Button1) { - struct client_ctx *cc; - cc = grab_menu_getcc(menuq, cur); - if (cc != NULL) { - client_unhide(cc); - XRaiseWindow(X_Dpy, - sc->menuwin); - } - } -#endif - xu_ptr_regrab(MenuGrabMask, Cursor_select); - XFillRectangle(X_Dpy, sc->menuwin, - sc->hlgc, 0, cur*high, wide, high); - } else - xu_ptr_regrab(MenuGrabMask, Cursor_default); + default: break; - case Expose: - XClearWindow(X_Dpy, sc->menuwin); - i = 0; - TAILQ_FOREACH(mi, menuq, entry) { - tx = (wide - font_width(font, mi->text, - strlen(mi->text)))/2; - ty = i*high + font_ascent(font) + 1; - font_draw(font, mi->text, strlen(mi->text), - sc->menuwin, tx, ty); - i++; - } - if (cur >= 0 && cur < n) - XFillRectangle(X_Dpy, sc->menuwin, - sc->hlgc, 0, cur*high, wide, high); - drawn = 1; } } } @@ -447,86 +355,7 @@ grab_label(struct client_ctx *cc) XUnmapWindow(X_Dpy, sc->searchwin); } -#define ExecMask (KeyPressMask|ExposureMask) - -void -grab_exec(void) -{ - int x, y, dx, dy, fontheight, focusrevert, len; - char cmdstr[MAXPATHLEN]; - char dispstr[MAXPATHLEN + sizeof("exec>") - 1]; - char chr, str[2]; - enum ctltype ctl; - struct fontdesc *font = DefaultFont; - struct screen_ctx *sc = screen_current(); - XEvent e; - Window focuswin; - - cmdstr[0] = '\0'; - - xu_ptr_getpos(sc->rootwin, &x, &y); - - dy = fontheight = font_ascent(font) + font_descent(font) + 1; - dx = font_width(font, "exec>", 5); - - XMoveResizeWindow(X_Dpy, sc->searchwin, x, y, dx, dy); - XSelectInput(X_Dpy, sc->searchwin, ExecMask); - XMapRaised(X_Dpy, sc->searchwin); - - XGetInputFocus(X_Dpy, &focuswin, &focusrevert); - XSetInputFocus(X_Dpy, sc->searchwin, - RevertToPointerRoot, CurrentTime); - - for (;;) { - XMaskEvent(X_Dpy, ExecMask, &e); - - switch (e.type) { - case KeyPress: - if (input_keycodetrans(e.xkey.keycode, e.xkey.state, - &ctl, &chr, 0) < 0) - continue; - - switch (ctl) { - case CTL_ERASEONE: - if ((len = strlen(cmdstr)) > 0) - cmdstr[len - 1] = '\0'; - break; - case CTL_RETURN: - if (strlen(cmdstr) > 0) - u_spawn(cmdstr); - goto out; - break; - case CTL_ABORT: - goto out; - default: - break; - } - - if (chr != '\0') { - str[0] = chr; - str[1] = '\0'; - strlcat(cmdstr, str, sizeof(cmdstr)); - } - case Expose: - snprintf(dispstr, sizeof(dispstr), "exec>%s", cmdstr); - - dx = font_width(font, dispstr, strlen(dispstr)); - dy = fontheight; - - XClearWindow(X_Dpy, sc->searchwin); - XResizeWindow(X_Dpy, sc->searchwin, dx, dy); - - font_draw(font, dispstr, strlen(dispstr), - sc->searchwin, 0, font_ascent(font) + 1); - break; - } - } - out: - XSetInputFocus(X_Dpy, focuswin, focusrevert, CurrentTime); - XUnmapWindow(X_Dpy, sc->searchwin); -} - -int +static int _sweepcalc(struct client_ctx *cc, int x0, int y0, int motionx, int motiony) { int width, height; @@ -560,12 +389,15 @@ _sweepcalc(struct client_ctx *cc, int x0, int y0, int motionx, int motiony) return (width != cc->geom.width || height != cc->geom.height); } -/* XXX */ -int -_nobuttons(XButtonEvent *e) /* Einstuerzende */ +static int +menu_calc_entry(int x, int y, int width, int height, int noentries) { - int state; + int entry = y/height; + + /* in bounds? */ + if (x < 0 || x > width || y < 0 || y > height*noentries || + entry < 0 || entry >= noentries) + entry = -1; - state = (e->state & AllButtonMask); - return (e->type == ButtonRelease) && (state & (state - 1)) == 0; + return entry; } |