summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--calmwm.c2
-rw-r--r--calmwm.h15
-rw-r--r--conf.c10
-rw-r--r--kbfunc.c19
-rw-r--r--menu.c82
-rw-r--r--screen.c45
6 files changed, 93 insertions, 80 deletions
diff --git a/calmwm.c b/calmwm.c
index 510bd33..b1c23ed 100644
--- a/calmwm.c
+++ b/calmwm.c
@@ -165,8 +165,6 @@ x_teardown(void)
 			    DefaultColormap(X_Dpy, sc->which),
 			    &sc->xftcolor[i]);
 		XftFontClose(X_Dpy, sc->xftfont);
-		XftDrawDestroy(sc->menu.xftdraw);
-		XDestroyWindow(X_Dpy, sc->menu.win);
 		XUngrabKey(X_Dpy, AnyKey, AnyModifier, sc->rootwin);
 	}
 	XUngrabPointer(X_Dpy, CurrentTime);
diff --git a/calmwm.h b/calmwm.h
index 32b7341..939f946 100644
--- a/calmwm.h
+++ b/calmwm.h
@@ -47,9 +47,6 @@
 
 #define BUTTONMASK	(ButtonPressMask | ButtonReleaseMask)
 #define MOUSEMASK	(BUTTONMASK | PointerMotionMask)
-#define MENUMASK 	(MOUSEMASK | ButtonMotionMask | KeyPressMask | \
-			 ExposureMask)
-#define MENUGRABMASK	(MOUSEMASK | ButtonMotionMask | StructureNotifyMask)
 #define IGNOREMODMASK	(LockMask | Mod2Mask | 0x2000)
 
 /* direction/amount */
@@ -229,7 +226,7 @@ struct screen_ctx {
 	struct {
 		Window		 win;
 		XftDraw		*xftdraw;
-	} menu;
+	} prop;
 	XftColor		 xftcolor[CWM_COLOR_NITEMS];
 	XftFont			*xftfont;
 };
@@ -484,6 +481,12 @@ void			 screen_init(int);
 void			 screen_update_geometry(struct screen_ctx *);
 void			 screen_updatestackingorder(struct screen_ctx *);
 void			 screen_assert_clients_within(struct screen_ctx *);
+void			 screen_prop_win_create(struct screen_ctx *, Window);
+void			 screen_prop_win_destroy(struct screen_ctx *);
+void			 screen_prop_win_draw(struct screen_ctx *,
+			     const char *, ...)
+			    __attribute__((__format__ (printf, 2, 3)))
+			    __attribute__((__nonnull__ (2)));
 
 void			 kbfunc_cwm_status(void *, struct cargs *);
 void			 kbfunc_ptrmove(void *, struct cargs *);
@@ -522,10 +525,6 @@ void			 kbfunc_exec_cmd(void *, struct cargs *);
 void			 kbfunc_exec_lock(void *, struct cargs *);
 void			 kbfunc_exec_term(void *, struct cargs *);
 
-void			 menu_windraw(struct screen_ctx *, Window,
-			     const char *, ...)
-			    __attribute__((__format__ (printf, 3, 4)))
-			    __attribute__((__nonnull__ (3)));
 struct menu  		*menu_filter(struct screen_ctx *, struct menu_q *,
 			     const char *, const char *, int,
 			     void (*)(struct menu_q *, struct menu_q *, char *),
diff --git a/conf.c b/conf.c
index d600728..30c803e 100644
--- a/conf.c
+++ b/conf.c
@@ -501,16 +501,6 @@ conf_screen(struct screen_ctx *sc)
 		}
 	}
 
-	sc->menu.win = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, 1, 1,
-	    Conf.bwidth,
-	    sc->xftcolor[CWM_COLOR_MENU_FG].pixel,
-	    sc->xftcolor[CWM_COLOR_MENU_BG].pixel);
-
-	sc->menu.xftdraw = XftDrawCreate(X_Dpy, sc->menu.win,
-	    sc->visual, sc->colormap);
-	if (sc->menu.xftdraw == NULL)
-		errx(1, "%s: XftDrawCreate", __func__);
-
 	conf_grab_kbd(sc->rootwin);
 }
 
diff --git a/kbfunc.c b/kbfunc.c
index 35b9b22..1858a42 100644
--- a/kbfunc.c
+++ b/kbfunc.c
@@ -166,8 +166,8 @@ kbfunc_client_move_mb(void *ctx, struct cargs *cargs)
 	    CurrentTime) != GrabSuccess)
 		return;
 
-	menu_windraw(sc, cc->win, "%4d, %-4d", cc->geom.x, cc->geom.y);
-
+	screen_prop_win_create(sc, cc->win);
+	screen_prop_win_draw(sc, "%+5d%+5d", cc->geom.x, cc->geom.y);
 	while (move) {
 		XMaskEvent(X_Dpy, MOUSEMASK, &ev);
 		switch (ev.type) {
@@ -190,8 +190,8 @@ kbfunc_client_move_mb(void *ctx, struct cargs *cargs)
 			    cc->geom.y + cc->geom.h + (cc->bwidth * 2),
 			    area.y, area.y + area.h, sc->snapdist);
 			client_move(cc);
-			menu_windraw(sc, cc->win,
-			    "%4d, %-4d", cc->geom.x, cc->geom.y);
+			screen_prop_win_draw(sc,
+			    "%+5d%+5d", cc->geom.x, cc->geom.y);
 			break;
 		case ButtonRelease:
 			move = 0;
@@ -200,8 +200,7 @@ kbfunc_client_move_mb(void *ctx, struct cargs *cargs)
 	}
 	if (ltime)
 		client_move(cc);
-	XUnmapWindow(X_Dpy, sc->menu.win);
-	XReparentWindow(X_Dpy, sc->menu.win, sc->rootwin, 0, 0);
+	screen_prop_win_destroy(sc);
 	XUngrabPointer(X_Dpy, CurrentTime);
 }
 
@@ -255,7 +254,8 @@ kbfunc_client_resize_mb(void *ctx, struct cargs *cargs)
 	    CurrentTime) != GrabSuccess)
 		return;
 
-	menu_windraw(sc, cc->win, "%4d x %-4d", cc->dim.w, cc->dim.h);
+	screen_prop_win_create(sc, cc->win);
+	screen_prop_win_draw(sc, "%4d x %-4d", cc->dim.w, cc->dim.h);
 	while (resize) {
 		XMaskEvent(X_Dpy, MOUSEMASK, &ev);
 		switch (ev.type) {
@@ -269,7 +269,7 @@ kbfunc_client_resize_mb(void *ctx, struct cargs *cargs)
 			cc->geom.h = ev.xmotion.y;
 			client_applysizehints(cc);
 			client_resize(cc, 1);
-			menu_windraw(sc, cc->win,
+			screen_prop_win_draw(sc,
 			    "%4d x %-4d", cc->dim.w, cc->dim.h);
 			break;
 		case ButtonRelease:
@@ -279,8 +279,7 @@ kbfunc_client_resize_mb(void *ctx, struct cargs *cargs)
 	}
 	if (ltime)
 		client_resize(cc, 1);
-	XUnmapWindow(X_Dpy, sc->menu.win);
-	XReparentWindow(X_Dpy, sc->menu.win, sc->rootwin, 0, 0);
+	screen_prop_win_destroy(sc);
 	XUngrabPointer(X_Dpy, CurrentTime);
 
 	/* Make sure the pointer stays within the window. */
diff --git a/menu.c b/menu.c
index d06c529..d0d3802 100644
--- a/menu.c
+++ b/menu.c
@@ -37,6 +37,10 @@
 #define PROMPT_SCHAR	"\xc2\xbb"
 #define PROMPT_ECHAR	"\xc2\xab"
 
+#define MENUMASK 	(MOUSEMASK | ButtonMotionMask | KeyPressMask | \
+			 ExposureMask)
+#define MENUGRABMASK	(MOUSEMASK | ButtonMotionMask | StructureNotifyMask)
+
 enum ctltype {
 	CTL_NONE = -1,
 	CTL_ERASEONE = 0, CTL_WIPE, CTL_UP, CTL_DOWN, CTL_RETURN,
@@ -45,6 +49,9 @@ enum ctltype {
 
 struct menu_ctx {
 	struct screen_ctx	*sc;
+	Window			 win;
+	XftDraw			*xftdraw;
+	struct geom		 geom;
 	char			 searchstr[MENU_MAXENTRY + 1];
 	char			 dispstr[MENU_MAXENTRY*2 + 1];
 	char			 promptstr[MENU_MAXENTRY + 1];
@@ -55,7 +62,6 @@ struct menu_ctx {
 	int			 entry;
 	int			 num;
 	int 			 flags;
-	struct geom		 geom;
 	void (*match)(struct menu_q *, struct menu_q *, char *);
 	void (*print)(struct menu *, int);
 };
@@ -108,27 +114,34 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, const char *prompt,
 	else
 		mc.searchstr[0] = '\0';
 
-	XSelectInput(X_Dpy, sc->menu.win, MENUMASK);
-	XMapRaised(X_Dpy, sc->menu.win);
+	mc.win = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, 1, 1,
+	    Conf.bwidth,
+	    sc->xftcolor[CWM_COLOR_MENU_FG].pixel,
+	    sc->xftcolor[CWM_COLOR_MENU_BG].pixel);
+	mc.xftdraw = XftDrawCreate(X_Dpy, mc.win,
+	    sc->visual, sc->colormap);
 
-	if (XGrabPointer(X_Dpy, sc->menu.win, False, MENUGRABMASK,
+	XSelectInput(X_Dpy, mc.win, MENUMASK);
+	XMapRaised(X_Dpy, mc.win);
+
+	if (XGrabPointer(X_Dpy, mc.win, False, MENUGRABMASK,
 	    GrabModeAsync, GrabModeAsync, None, Conf.cursor[CF_QUESTION],
 	    CurrentTime) != GrabSuccess) {
-		XUnmapWindow(X_Dpy, sc->menu.win);
-		return(NULL);
+		XftDrawDestroy(mc.xftdraw);
+		XDestroyWindow(X_Dpy, mc.win);
 	}
 
 	XGetInputFocus(X_Dpy, &focuswin, &focusrevert);
-	XSetInputFocus(X_Dpy, sc->menu.win, RevertToPointerRoot, CurrentTime);
+	XSetInputFocus(X_Dpy, mc.win, RevertToPointerRoot, CurrentTime);
 
 	/* make sure keybindings don't remove keys from the menu stream */
-	XGrabKeyboard(X_Dpy, sc->menu.win, True,
+	XGrabKeyboard(X_Dpy, mc.win, True,
 	    GrabModeAsync, GrabModeAsync, CurrentTime);
 
 	for (;;) {
 		mc.changed = 0;
 
-		XWindowEvent(X_Dpy, sc->menu.win, MENUMASK, &e);
+		XWindowEvent(X_Dpy, mc.win, MENUMASK, &e);
 
 		switch (e.type) {
 		case KeyPress:
@@ -159,16 +172,16 @@ out:
 		mi = NULL;
 	}
 
-	XSelectInput(X_Dpy, sc->menu.win, NoEventMask);
+	XftDrawDestroy(mc.xftdraw);
+	XDestroyWindow(X_Dpy, mc.win);
+
 	XSetInputFocus(X_Dpy, focuswin, focusrevert, CurrentTime);
 	/* restore if user didn't move */
 	xu_ptr_getpos(sc->rootwin, &xcur, &ycur);
 	if (xcur == mc.geom.x && ycur == mc.geom.y)
 		xu_ptr_setpos(sc->rootwin, xsave, ysave);
-	XUngrabPointer(X_Dpy, CurrentTime);
 
-	XMoveResizeWindow(X_Dpy, sc->menu.win, 0, 0, 1, 1);
-	XUnmapWindow(X_Dpy, sc->menu.win);
+	XUngrabPointer(X_Dpy, CurrentTime);
 	XUngrabKeyboard(X_Dpy, CurrentTime);
 
 	return(mi);
@@ -378,12 +391,12 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq)
 	if (mc->geom.x != xsave || mc->geom.y != ysave)
 		xu_ptr_setpos(sc->rootwin, mc->geom.x, mc->geom.y);
 
-	XClearWindow(X_Dpy, sc->menu.win);
-	XMoveResizeWindow(X_Dpy, sc->menu.win, mc->geom.x, mc->geom.y,
+	XClearWindow(X_Dpy, mc->win);
+	XMoveResizeWindow(X_Dpy, mc->win, mc->geom.x, mc->geom.y,
 	    mc->geom.w, mc->geom.h);
 
 	n = 1;
-	XftDrawStringUtf8(sc->menu.xftdraw,
+	XftDrawStringUtf8(mc->xftdraw,
 	    &sc->xftcolor[CWM_COLOR_MENU_FONT], sc->xftfont,
 	    0, sc->xftfont->ascent,
 	    (const FcChar8*)mc->dispstr, strlen(mc->dispstr));
@@ -395,7 +408,7 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq)
 		if (mc->geom.y + y > area.h)
 			break;
 
-		XftDrawStringUtf8(sc->menu.xftdraw,
+		XftDrawStringUtf8(mc->xftdraw,
 		    &sc->xftcolor[CWM_COLOR_MENU_FONT], sc->xftfont,
 		    0, y,
 		    (const FcChar8*)mi->print, strlen(mi->print));
@@ -420,11 +433,11 @@ menu_draw_entry(struct menu_ctx *mc, struct menu_q *resultq,
 		return;
 
 	color = (active) ? CWM_COLOR_MENU_FG : CWM_COLOR_MENU_BG;
-	XftDrawRect(sc->menu.xftdraw, &sc->xftcolor[color], 0,
+	XftDrawRect(mc->xftdraw, &sc->xftcolor[color], 0,
 	    (sc->xftfont->height + 1) * entry, mc->geom.w,
 	    (sc->xftfont->height + 1) + sc->xftfont->descent);
 	color = (active) ? CWM_COLOR_MENU_FONT_SEL : CWM_COLOR_MENU_FONT;
-	XftDrawStringUtf8(sc->menu.xftdraw,
+	XftDrawStringUtf8(mc->xftdraw,
 	    &sc->xftcolor[color], sc->xftfont,
 	    0, (sc->xftfont->height + 1) * entry + sc->xftfont->ascent + 1,
 	    (const FcChar8*)mi->print, strlen(mi->print));
@@ -604,34 +617,3 @@ menuq_clear(struct menu_q *mq)
 		free(mi);
 	}
 }
-
-void
-menu_windraw(struct screen_ctx *sc, Window win, const char *fmt, ...)
-{
-	va_list			 ap;
-	int			 i;
-	char			*text;
-	XGlyphInfo		 extents;
-
-	va_start(ap, fmt);
-	i = vasprintf(&text, fmt, ap);
-	va_end(ap);
-
-	if (i < 0 || text == NULL)
-		err(1, "vasprintf");
-
-	XftTextExtentsUtf8(X_Dpy, sc->xftfont, (const FcChar8*)text,
-	    strlen(text), &extents);
-
-	XReparentWindow(X_Dpy, sc->menu.win, win, 0, 0);
-	XMoveResizeWindow(X_Dpy, sc->menu.win, 0, 0,
-	    extents.xOff, sc->xftfont->height);
-	XMapWindow(X_Dpy, sc->menu.win);
-	XClearWindow(X_Dpy, sc->menu.win);
-
-	XftDrawStringUtf8(sc->menu.xftdraw, &sc->xftcolor[CWM_COLOR_MENU_FONT],
-	    sc->xftfont, 0, sc->xftfont->ascent + 1,
-	    (const FcChar8*)text, strlen(text));
-
-	free(text);
-}
diff --git a/screen.c b/screen.c
index a449219..eb84a17 100644
--- a/screen.c
+++ b/screen.c
@@ -24,6 +24,7 @@
 #include <err.h>
 #include <errno.h>
 #include <limits.h>
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -250,3 +251,47 @@ screen_assert_clients_within(struct screen_ctx *sc)
 		}
 	}
 }
+
+void
+screen_prop_win_create(struct screen_ctx *sc, Window win)
+{
+	sc->prop.win = XCreateSimpleWindow(X_Dpy, win, 0, 0, 1, 1, 0,
+	    sc->xftcolor[CWM_COLOR_MENU_BG].pixel,
+	    sc->xftcolor[CWM_COLOR_MENU_BG].pixel);
+	sc->prop.xftdraw = XftDrawCreate(X_Dpy, sc->prop.win,
+	    sc->visual, sc->colormap);
+
+	XMapWindow(X_Dpy, sc->prop.win);
+}
+
+void
+screen_prop_win_destroy(struct screen_ctx *sc)
+{
+	XftDrawDestroy(sc->prop.xftdraw);
+	XDestroyWindow(X_Dpy, sc->prop.win);
+}
+
+void
+screen_prop_win_draw(struct screen_ctx *sc, const char *fmt, ...)
+{
+	va_list			 ap;
+	int			 i;
+	char			*text;
+	XGlyphInfo		 extents;
+
+	va_start(ap, fmt);
+	i = vasprintf(&text, fmt, ap);
+	va_end(ap);
+	if (i < 0 || text == NULL)
+		err(1, "vasprintf");
+
+	XftTextExtentsUtf8(X_Dpy, sc->xftfont, (const FcChar8*)text,
+	    strlen(text), &extents);
+	XResizeWindow(X_Dpy, sc->prop.win, extents.xOff, sc->xftfont->height);
+	XClearWindow(X_Dpy, sc->prop.win);
+	XftDrawStringUtf8(sc->prop.xftdraw, &sc->xftcolor[CWM_COLOR_MENU_FONT],
+	    sc->xftfont, 0, sc->xftfont->ascent + 1,
+	    (const FcChar8*)text, strlen(text));
+
+	free(text);
+}