From 0bda8f76067b737f34c11ef094b349c0c12fe118 Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 4 Mar 2019 19:28:17 +0000 Subject: Separate out the menu window from the client resize/move geom window; in each case, create and destroy on-demand. Isolate more menu specific code. --- calmwm.c | 2 -- calmwm.h | 15 ++++++------ conf.c | 10 -------- kbfunc.c | 19 +++++++-------- menu.c | 82 +++++++++++++++++++++++++--------------------------------------- screen.c | 45 +++++++++++++++++++++++++++++++++++ 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 #include #include +#include #include #include #include @@ -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); +} -- cgit 1.4.1