summary refs log tree commit diff
diff options
context:
space:
mode:
authoroga <oga>2008-01-14 15:21:10 +0000
committeroga <oga>2008-01-14 15:21:10 +0000
commit1eed217b1c54d32d3c9269be79c3cb298b4b2805 (patch)
tree2d60320821b0fa134774a1a50ac4016c58793d2c
parente5cabb0f43a4e584f09bda9fc3423f0df7a295d3 (diff)
downloadcwm-1eed217b1c54d32d3c9269be79c3cb298b4b2805.tar.gz
cwm-1eed217b1c54d32d3c9269be79c3cb298b4b2805.tar.xz
cwm-1eed217b1c54d32d3c9269be79c3cb298b4b2805.zip
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@.
-rw-r--r--calmwm.c6
-rw-r--r--calmwm.h6
-rw-r--r--grab.c334
-rw-r--r--group.c2
4 files changed, 88 insertions, 260 deletions
diff --git a/calmwm.c b/calmwm.c
index 7550bc8..5c91b2f 100644
--- a/calmwm.c
+++ b/calmwm.c
@@ -50,7 +50,6 @@ static char gray_bits[] = {0x02, 0x01};
 /* List borrowed from 9wm/rio */
 char *tryfonts[] = {
 	"9x15bold",
-	"blit",
 	"*-lucidatypewriter-bold-*-14-*-75-*",
 	"*-lucidatypewriter-medium-*-12-*-75-*",
 	"fixed",
@@ -161,9 +160,7 @@ x_setup(char *display_name)
 	Cursor_resize = XCreateFontCursor(X_Dpy, XC_bottom_right_corner);
 	/* (used to be) XCreateFontCursor(X_Dpy, XC_hand1); */
 	Cursor_select = XCreateFontCursor(X_Dpy, XC_hand1);
-/* 	Cursor_select = cursor_bigarrow(Curscreen); */
 	Cursor_default = XCreateFontCursor(X_Dpy, XC_X_cursor);
-/* 	Cursor_default = cursor_bigarrow(Curscreen); */
 	Cursor_question = XCreateFontCursor(X_Dpy, XC_question_arrow);
 }
 
@@ -288,9 +285,6 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
 	rootattr.event_mask = ChildMask|PropertyChangeMask|EnterWindowMask|
 	    LeaveWindowMask|ColormapChangeMask|ButtonMask;
 
-	/* Set the root cursor to a nice obnoxious arrow :-) */
-/* 	rootattr.cursor = cursor_bigarrow(sc); */
-
 	XChangeWindowAttributes(X_Dpy, sc->rootwin,
 	    /* CWCursor| */CWEventMask, &rootattr);
 
diff --git a/calmwm.h b/calmwm.h
index 3f8bfec..dd9371c 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -79,6 +79,10 @@ struct screen_ctx {
 
 	int		 altpersist;
 
+	int		 maxinitialised;
+	int		 xmax;
+	int		 ymax;
+
         FILE            *notifier;
 
 	struct cycle_entry_q mruq;
@@ -276,7 +280,6 @@ struct menu {
 	char  text[MENU_MAXENTRY + 1];
 	char  print[MENU_MAXENTRY + 1];
 	void *ctx;
-	short lasthit;
 	short dummy;
 };
 
@@ -399,7 +402,6 @@ int   grab_drag(struct client_ctx *);
 void  grab_menuinit(struct screen_ctx *);
 void *grab_menu(XButtonEvent *, struct menu_q *);
 void  grab_label(struct client_ctx *);
-void  grab_exec(void);
 
 void  xfree(void *);
 void *xmalloc(size_t);
diff --git a/grab.c b/grab.c
index 5aa3a06..f55459a 100644
--- a/grab.c
+++ b/grab.c
@@ -21,8 +21,8 @@
 #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;
 }
diff --git a/group.c b/group.c
index 64857c1..c9cccef 100644
--- a/group.c
+++ b/group.c
@@ -92,7 +92,7 @@ _group_purge(struct group_ctx *gc)
 	struct client_ctx *cc;
 
 	if (gc == NULL)
-		errx(1, "_group_commit: ctx is null");
+		errx(1, "_group_purge: ctx is null");
 
 	TAILQ_FOREACH(cc, &gc->clients, group_entry)
 		if (cc->groupcommit == 0)