diff --git a/calmwm.h b/calmwm.h index 8baea11..99bad1f 100644 --- a/calmwm.h +++ b/calmwm.h @@ -94,6 +94,7 @@ size_t strlcpy(char *, const char *, size_t); /* menu */ #define CWM_MENU_DUMMY 0x0001 #define CWM_MENU_FILE 0x0002 +#define CWM_MENU_LIST 0x0004 #define ARG_CHAR 0x0001 #define ARG_INT 0x0002 @@ -189,6 +190,10 @@ struct client_ctx { int x; /* x position */ int y; /* y position */ } ptr; + struct { + int h; /* height */ + int w; /* width */ + } dim; #define CLIENT_HIDDEN 0x0001 #define CLIENT_IGNORE 0x0002 #define CLIENT_VMAXIMIZED 0x0004 @@ -325,11 +330,27 @@ struct mwm_hints { unsigned long functions; unsigned long decorations; }; -#define MWM_NUMHINTS 3 -#define PROP_MWM_HINTS_ELEMENTS 3 -#define MWM_HINTS_DECORATIONS (1<<1) +#define MWM_HINTS_ELEMENTS 3L + +#define MWM_FLAGS_FUNCTIONS (1<<0) +#define MWM_FLAGS_DECORATIONS (1<<1) +#define MWM_FLAGS_INPUT_MODE (1<<2) +#define MWM_FLAGS_STATUS (1<<3) + +#define MWM_FUNCS_ALL (1<<0) +#define MWM_FUNCS_RESIZE (1<<1) +#define MWM_FUNCS_MOVE (1<<2) +#define MWM_FUNCS_MINIMIZE (1<<3) +#define MWM_FUNCS_MAXIMIZE (1<<4) +#define MWM_FUNCS_CLOSE (1<<5) + #define MWM_DECOR_ALL (1<<0) #define MWM_DECOR_BORDER (1<<1) +#define MWM_DECOR_RESIZE_HANDLE (1<<2) +#define MWM_DECOR_TITLEBAR (1<<3) +#define MWM_DECOR_MENU (1<<4) +#define MWM_DECOR_MINIMIZE (1<<5) +#define MWM_DECOR_MAXIMIZE (1<<6) extern Display *X_Dpy; extern Time Last_Event_Time; @@ -500,8 +521,6 @@ void kbfunc_ssh(struct client_ctx *, union arg *); void kbfunc_term(struct client_ctx *, union arg *); void kbfunc_tile(struct client_ctx *, union arg *); -void mousefunc_client_grouptoggle(struct client_ctx *, - union arg *); void mousefunc_client_move(struct client_ctx *, union arg *); void mousefunc_client_resize(struct client_ctx *, @@ -521,7 +540,8 @@ void menuq_clear(struct menu_q *); int parse_config(const char *, struct conf *); void conf_atoms(void); -void conf_autogroup(struct conf *, int, const char *); +void conf_autogroup(struct conf *, int, const char *, + const char *); int conf_bind_kbd(struct conf *, const char *, const char *); int conf_bind_mouse(struct conf *, const char *, diff --git a/client.c b/client.c index 70a94af..f8b4e92 100644 --- a/client.c +++ b/client.c @@ -874,6 +874,9 @@ client_applysizehints(struct client_ctx *cc) cc->geom.w = MAX(cc->geom.w, 1); cc->geom.h = MAX(cc->geom.h, 1); + + cc->dim.w = (cc->geom.w - cc->hint.basew) / cc->hint.incw; + cc->dim.h = (cc->geom.h - cc->hint.baseh) / cc->hint.inch; } static void @@ -882,8 +885,8 @@ client_mwm_hints(struct client_ctx *cc) struct mwm_hints *mwmh; if (xu_getprop(cc->win, cwmh[_MOTIF_WM_HINTS], cwmh[_MOTIF_WM_HINTS], - PROP_MWM_HINTS_ELEMENTS, (unsigned char **)&mwmh) == MWM_NUMHINTS) { - if (mwmh->flags & MWM_HINTS_DECORATIONS && + MWM_HINTS_ELEMENTS, (unsigned char **)&mwmh) == MWM_HINTS_ELEMENTS) { + if (mwmh->flags & MWM_FLAGS_DECORATIONS && !(mwmh->decorations & MWM_DECOR_ALL) && !(mwmh->decorations & MWM_DECOR_BORDER)) cc->bwidth = 0; diff --git a/conf.c b/conf.c index da51d4e..ce867cb 100644 --- a/conf.c +++ b/conf.c @@ -71,19 +71,28 @@ conf_cmd_remove(struct conf *c, const char *name) } } void -conf_autogroup(struct conf *c, int num, const char *val) +conf_autogroup(struct conf *c, int num, const char *name, const char *class) { struct autogroupwin *aw; char *p; aw = xmalloc(sizeof(*aw)); - if ((p = strchr(val, ',')) == NULL) { - aw->name = NULL; - aw->class = xstrdup(val); + if ((p = strchr(class, ',')) == NULL) { + if (name == NULL) + aw->name = NULL; + else + aw->name = xstrdup(name); + + aw->class = xstrdup(class); } else { *(p++) = '\0'; - aw->name = xstrdup(val); + + if (name == NULL) + aw->name = xstrdup(class); + else + aw->name = xstrdup(name); + aw->class = xstrdup(p); } aw->num = num; @@ -382,7 +391,7 @@ static const struct { {.i = CWM_CYCLE|CWM_INGROUP} }, { "rcycleingroup", kbfunc_client_cycle, CWM_WIN, {.i = CWM_RCYCLE|CWM_INGROUP} }, - { "grouptoggle", kbfunc_client_grouptoggle, CWM_WIN, {0}}, + { "grouptoggle", kbfunc_client_grouptoggle, CWM_WIN, {.i = 0}}, { "sticky", kbfunc_client_toggle_sticky, CWM_WIN, {0} }, { "fullscreen", kbfunc_client_toggle_fullscreen, CWM_WIN, {0} }, { "maximize", kbfunc_client_toggle_maximize, CWM_WIN, {0} }, @@ -451,7 +460,7 @@ static const struct { { "window_hide", kbfunc_client_hide, CWM_WIN, {0} }, { "window_move", mousefunc_client_move, CWM_WIN, {0} }, { "window_resize", mousefunc_client_resize, CWM_WIN, {0} }, - { "window_grouptoggle", mousefunc_client_grouptoggle, CWM_WIN, {0} }, + { "window_grouptoggle", kbfunc_client_grouptoggle, CWM_WIN, {.i = 1} }, { "menu_group", mousefunc_menu_group, 0, {0} }, { "menu_unhide", mousefunc_menu_unhide, 0, {0} }, { "menu_cmd", mousefunc_menu_cmd, 0, {0} }, diff --git a/cwm.1 b/cwm.1 index eb6c9e7..e4776ca 100644 --- a/cwm.1 +++ b/cwm.1 @@ -28,19 +28,40 @@ .Sh DESCRIPTION .Nm is a window manager for X11 which contains many features that -concentrate on the efficiency and transparency of window management. -.Nm -also aims to maintain the simplest and most pleasant aesthetic. +concentrate on the efficiency and transparency of window management, +while maintaining the simplest and most pleasant aesthetic. .Pp -The following notation is used throughout this page: +The options are as follows: +.Bl -tag -width Ds +.It Fl c Ar file +Specify an alternative configuration file. +By default, +.Nm +loads +.Pa ~/.cwmrc , +if present. +Any error messages from lines in the configuration file will be sent to +.Em stderr ; +however, +.Nm +will continue to process the rest of the configuration file. +.It Fl d Ar display +Specify the display to use. +.El +.Pp +.Nm +actions are initiated either via key or mouse bindings. +The following notations are used throughout this page: .Pp .Bl -tag -width Ds -offset indent -compact .It Ic C -Control. +Control key. .It Ic M -Meta. +Meta key. .It Ic S -Shift. +Shift key. +.It Ic 4 +Mod4 (windows) key. .It Ic M1 Left mouse button. .It Ic M2 @@ -49,11 +70,7 @@ Middle mouse button. Right mouse button. .El .Pp -.Nm -is very simple in its use. -Most of the actions are initiated via key bindings. -The default key bindings are described below; -their functionality is described in more detail later. +The default key bindings are: .Pp .Bl -tag -width "CM-EscapeXXXXX" -offset indent -compact .It Ic CM-Return @@ -100,6 +117,21 @@ Toggle maximization of current window. Toggle vertical maximization of current window. .It Ic CMS-= Toggle horizontal maximization of current window. +.It Ic C-[Up|Down|Left|Right] +Move pointer by a small amount. +.It Ic CS-[Up|Down|Left|Right] +Move pointer by a large amount; see +.Xr cwmrc 5 . +.It Ic M-[hjkl] +Move window by a small amount. +.It Ic MS-[hjkl] +Move window by a large amount; see +.Xr cwmrc 5 . +.It Ic CM-[hjkl] +Resize window by a small amount. +.It Ic CMS-[hjkl] +Resize window by a large amount; see +.Xr cwmrc 5 . .It Ic M-? Spawn .Dq exec program @@ -116,20 +148,16 @@ will be executed via the configured terminal emulator. .It Ic CM-w Spawn .Dq exec WindowManager -dialog; allows you to switch from -.Nm -to another window manager without restarting the X server. +dialog, allowing a switch to another window manager. .It Ic CMS-r -Restart the running -.Xr cwm 1 . +Restart. .It Ic CMS-q -Quit -.Nm . +Quit. .El .Pp The default mouse bindings are: .Pp -.Bl -tag -width Ds -offset indent -compact +.Bl -tag -width "CM-EscapeXXXXX" -offset indent -compact .It Ic M-M1 Move current window. .It Ic CM-M1 @@ -142,56 +170,25 @@ Lower current window. Hide current window. .El .Pp -The options for -.Nm -are as follows: -.Bl -tag -width Ds -.It Fl c Ar file -Specify an alternative configuration file. -By default, -.Nm -loads -.Pa ~/.cwmrc , -if present. -Any error messages from lines in the configuration file will be sent to -.Em stderr ; -however, -.Nm -will continue to process the rest of the configuration file. -.It Fl d Ar display -Specify the display to use. -.El -.Sh POINTER MOVEMENT -The pointer can be moved with the use of the keyboard through bindings. -.Ic C-[Up|Down|Left|Right] -moves the pointer a small amount, while -.Ic CS-[Up|Down|Left|Right] -moves the pointer a larger amount. -For example, to move the pointer to the left by a small amount, -press -.Ic C-Left . -To move the pointer down by a larger amount, press -.Ic CS-Down . -.Sh WINDOW MOVEMENT AND RESIZING -.Nm -windows can be moved with the use of the keyboard through -.Cm vi Ns -like -bindings. -.Ic M-[hjkl] -moves the current window a small amount, while -.Ic MS-[hjkl] -moves the current window a larger amount. -For example, to move the current window to the left a small amount, press -.Ic M-h . -To move the current window down by a larger amount, press -.Ic MS-j . +The following key bindings may be used to navigate +search and exec dialogs: .Pp -Similarly, windows may be resized with the same key bindings with the addition -of the Control key. -.Ic CM-[hjkl] -resizes the window a small amount and -.Ic CMS-[hjkl] -resizes by a larger increment. +.Bl -tag -width "[Down] or C-s or M-j" -offset indent -compact +.It Ic [Return] +Select item. +.It Ic [Down], C-s No or Ic M-j +Next item. +.It Ic [Up], C-r No or Ic M-k +Previous item. +.It Ic [Backspace] No or Ic C-h +Backspace. +.It Ic C-u +Clear input. +.It Ic C-a +List all available items. +.It Ic [Esc] +Cancel. +.El .Sh SEARCH .Nm features the ability to search for windows by their current title, @@ -204,37 +201,16 @@ keeps a history of the 5 previous titles of a window. When searching, the leftmost character of the result list may show a flag: .Pp -.Bl -tag -width 10n -offset indent -compact +.Bl -tag -width Ds -offset indent -compact .It ! -The window is the currently focused window. +Window is currently focused. .It & -The window is hidden. -.El -.Pp -The following key bindings may be used to navigate the result list: -.Pp -.Bl -tag -width "[Down] or C-s or M-j" -offset indent -compact -.It Ic [Down], C-s No or Ic M-j -Select the next window in the list. -.It Ic [Up], C-r No or Ic M-k -Select the previous window in the list. -.It Ic [Backspace] No or Ic C-h -Backspace. -.It Ic C-u -Clear the input. -.It Ic [Return] -Focus the selected window. -.It Ic [Esc] -Cancel. -.It Ic C-a -Whenever there are no matching windows, list every window. +Window is hidden. .El .Sh GROUPS .Nm has the ability to group windows together, and use the groups to perform operations on the entire group instead of just one window. -Currently, the only operation that is supported is to hide and unhide -the grouped windows. Together with the .Pa sticky option, this can be used to emulate virtual desktops. @@ -246,20 +222,20 @@ and a red border will be shown on those just removed. .Sh MENUS Menus are recalled by clicking the mouse on the root window: .Pp -.Bl -tag -width 10n -offset indent -compact +.Bl -tag -width Ds -offset indent -compact .It Ic M1 Show list of currently hidden windows. -Clicking on an item will unhide that window. +Selecting an item will unhide that window. .It Ic M2 Show list of currently defined groups. -Clicking on an item will hide/unhide that group. +Selecting an item will hide/unhide that group. .It Ic M3 Show list of applications as defined in .Pa ~/.cwmrc . -Clicking on an item will spawn that application. +Selecting an item will spawn that application. .El .Sh ENVIRONMENT -.Bl -tag -width "DISPLAYXXX" +.Bl -tag -width "DISPLAYXXX" -compact .It DISPLAY .Nm starts on this display unless the @@ -267,8 +243,11 @@ starts on this display unless the option is given. .El .Sh FILES -.Bl -tag -width Ds +.Bl -tag -width "~/.cwmrcXX" -compact .It Pa ~/.cwmrc +Default +.Nm +configuration file. .El .Sh SEE ALSO .Xr cwmrc 5 diff --git a/cwmrc.5 b/cwmrc.5 index a0b39d3..093060b 100644 --- a/cwmrc.5 +++ b/cwmrc.5 @@ -72,14 +72,14 @@ The modifier keys come first, followed by a The following modifiers are recognised: .Pp .Bl -tag -width Ds -offset indent -compact -.It C -The Control key. -.It M -The Meta key. -.It S -The Shift key. -.It 4 -The Mod4 key (normally the windows key). +.It Ic C +Control key. +.It Ic M +Meta key. +.It Ic S +Shift key. +.It Ic 4 +Mod4 (windows) key. .El .Pp The @@ -186,14 +186,14 @@ The modifier keys come first, followed by a The following modifiers are recognised: .Pp .Bl -tag -width Ds -offset indent -compact -.It C -The Control key. -.It M -The Meta key. -.It S -The Shift key. -.It 4 -The Mod4 key (normally the windows key). +.It Ic C +Control key. +.It Ic M +Meta key. +.It Ic S +Shift key. +.It Ic 4 +Mod4 (windows) key. .El .Pp The @@ -201,15 +201,15 @@ The should be followed by number: .Pp .Bl -tag -width Ds -offset indent -compact -.It 1 +.It Ic 1 Left mouse button. -.It 2 +.It Ic 2 Middle mouse button. -.It 3 +.It Ic 3 Right mouse button. -.It 4 +.It Ic 4 Scroll up mouse button. -.It 5 +.It Ic 5 Scroll down mouse button. .El .Pp @@ -235,48 +235,6 @@ By enabling sticky group mode, .Xr cwm 1 will assign new windows to the currently selected group. .El -.Sh EXAMPLE CONFIGURATION -.Bd -literal -# Set default Xft(3) font -fontname "sans-serif:pixelsize=14:bold" - -# Turn on sticky-group mode -sticky yes - -# Any entry here is shown in the application menu -command firefox firefox -command xmms xmms -command top "xterm -e top" - -# Autogroup definitions -autogroup 3 "aterm,XTerm" -autogroup 3 "xterm,XTerm" - -# Ignore programs by that name by not drawing borders around them. -ignore XMMS -ignore xwi -ignore xapm -ignore xclock - -# Key bindings -bind CM-r label -bind CS-Return "xterm -e top" -bind 4-o unmap -bind CM-equal unmap -bind CMS-equal unmap -bind C4-equal vmaximize -bind C4S-equal hmaximize -bind M-1 grouponly1 -bind M-2 grouponly2 -bind M-3 grouponly3 -bind MS-1 movetogroup1 -bind MS-2 movetogroup2 -bind MS-3 movetogroup3 - -# Mouse bindings -mousebind M-2 window_lower -mousebind M-3 window_resize -.Ed .Sh BIND COMMAND LIST .Bl -tag -width 18n -compact .It restart @@ -482,10 +440,52 @@ Launch command list. .Sh FILES .Bl -tag -width "~/.cwmrcXXX" -compact .It Pa ~/.cwmrc -default +Default .Xr cwm 1 -configuration file +configuration file. .El +.Sh EXAMPLES +.Bd -literal +# Set default Xft(3) font +fontname "sans-serif:pixelsize=14:bold" + +# Turn on sticky-group mode +sticky yes + +# Any entry here is shown in the application menu +command firefox firefox +command xmms xmms +command top "xterm -e top" + +# Autogroup definitions +autogroup 3 "aterm,XTerm" +autogroup 3 "xterm,XTerm" + +# Ignore programs by that name by not drawing borders around them. +ignore XMMS +ignore xwi +ignore xapm +ignore xclock + +# Key bindings +bind CM-r label +bind CS-Return "xterm -e top" +bind 4-o unmap +bind CM-equal unmap +bind CMS-equal unmap +bind C4-equal vmaximize +bind C4S-equal hmaximize +bind M-1 grouponly1 +bind M-2 grouponly2 +bind M-3 grouponly3 +bind MS-1 movetogroup1 +bind MS-2 movetogroup2 +bind MS-3 movetogroup3 + +# Mouse bindings +mousebind M-2 window_lower +mousebind M-3 window_resize +.Ed .Sh SEE ALSO .Xr cwm 1 .Sh HISTORY diff --git a/kbfunc.c b/kbfunc.c index 476f570..68c91fa 100644 --- a/kbfunc.c +++ b/kbfunc.c @@ -153,7 +153,7 @@ kbfunc_client_search(struct client_ctx *cc, union arg *arg) TAILQ_INIT(&menuq); TAILQ_FOREACH(cc, &sc->clientq, entry) - menuq_add(&menuq, cc, "%s", cc->name); + menuq_add(&menuq, cc, NULL); if ((mi = menu_filter(sc, &menuq, "window", NULL, 0, search_match_client, search_print_client)) != NULL) { @@ -441,9 +441,11 @@ kbfunc_client_nogroup(struct client_ctx *cc, union arg *arg) void kbfunc_client_grouptoggle(struct client_ctx *cc, union arg *arg) { - /* XXX for stupid X apps like xpdf and gvim */ - XGrabKeyboard(X_Dpy, cc->win, True, - GrabModeAsync, GrabModeAsync, CurrentTime); + if (arg->i == 0) { + /* XXX for stupid X apps like xpdf and gvim */ + XGrabKeyboard(X_Dpy, cc->win, True, + GrabModeAsync, GrabModeAsync, CurrentTime); + } group_toggle_membership_enter(cc); } diff --git a/menu.c b/menu.c index 2d8853c..f0b864b 100644 --- a/menu.c +++ b/menu.c @@ -55,12 +55,9 @@ struct menu_ctx { int noresult; int prev; int entry; - int height; - int width; int num; int flags; - int x; - int y; + struct geom geom; void (*match)(struct menu_q *, struct menu_q *, char *); void (*print)(struct menu *, int); }; @@ -96,30 +93,30 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, const char *prompt, (void)memset(&mc, 0, sizeof(mc)); - xu_ptr_getpos(sc->rootwin, &mc.x, &mc.y); - - xsave = mc.x; - ysave = mc.y; + xu_ptr_getpos(sc->rootwin, &xsave, &ysave); mc.sc = sc; mc.flags = flags; - if (prompt != NULL) { - evmask = MENUMASK | KEYMASK; /* accept keys as well */ - (void)strlcpy(mc.promptstr, prompt, sizeof(mc.promptstr)); - mc.hasprompt = 1; - } else { - evmask = MENUMASK; + mc.match = match; + mc.print = print; + mc.entry = mc.prev = -1; + mc.geom.x = xsave; + mc.geom.y = ysave; + + if (mc.flags & CWM_MENU_LIST) mc.list = 1; - } if (initial != NULL) (void)strlcpy(mc.searchstr, initial, sizeof(mc.searchstr)); else mc.searchstr[0] = '\0'; - mc.match = match; - mc.print = print; - mc.entry = mc.prev = -1; + evmask = MENUMASK; + if (prompt != NULL) { + evmask |= KEYMASK; /* accept keys as well */ + (void)strlcpy(mc.promptstr, prompt, sizeof(mc.promptstr)); + mc.hasprompt = 1; + } XSelectInput(X_Dpy, sc->menuwin, evmask); XMapRaised(X_Dpy, sc->menuwin); @@ -173,7 +170,7 @@ out: XSetInputFocus(X_Dpy, focuswin, focusrevert, CurrentTime); /* restore if user didn't move */ xu_ptr_getpos(sc->rootwin, &xcur, &ycur); - if (xcur == mc.x && ycur == mc.y) + if (xcur == mc.geom.x && ycur == mc.geom.y) xu_ptr_setpos(sc->rootwin, xsave, ysave); xu_ptr_ungrab(); @@ -338,11 +335,10 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq) int n, xsave, ysave; if (mc->list) { - if (TAILQ_EMPTY(resultq) && mc->list) { + if (TAILQ_EMPTY(resultq)) { /* Copy them all over. */ TAILQ_FOREACH(mi, menuq, entry) - TAILQ_INSERT_TAIL(resultq, mi, - resultentry); + TAILQ_INSERT_TAIL(resultq, mi, resultentry); mc->listing = 1; } else if (mc->changed) @@ -350,14 +346,14 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq) } mc->num = 0; - mc->width = 0; - mc->height = 0; + mc->geom.w = 0; + mc->geom.h = 0; if (mc->hasprompt) { (void)snprintf(mc->dispstr, sizeof(mc->dispstr), "%s%s%s%s", mc->promptstr, PROMPT_SCHAR, mc->searchstr, PROMPT_ECHAR); - mc->width = xu_xft_width(sc->xftfont, mc->dispstr, + mc->geom.w = xu_xft_width(sc->xftfont, mc->dispstr, strlen(mc->dispstr)); - mc->height = sc->xftfont->height + 1; + mc->geom.h = sc->xftfont->height + 1; mc->num = 1; } @@ -372,39 +368,39 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq) text = mi->text; } - mc->width = MAX(mc->width, xu_xft_width(sc->xftfont, text, + mc->geom.w = MAX(mc->geom.w, xu_xft_width(sc->xftfont, text, MIN(strlen(text), MENU_MAXENTRY))); - mc->height += sc->xftfont->height + 1; + mc->geom.h += sc->xftfont->height + 1; mc->num++; } - xine = screen_find_xinerama(sc, mc->x, mc->y, CWM_GAP); + xine = screen_find_xinerama(sc, mc->geom.x, mc->geom.y, CWM_GAP); xine.w += xine.x - Conf.bwidth * 2; xine.h += xine.y - Conf.bwidth * 2; - xsave = mc->x; - ysave = mc->y; + xsave = mc->geom.x; + ysave = mc->geom.y; /* Never hide the top, or left side, of the menu. */ - if (mc->x + mc->width >= xine.w) - mc->x = xine.w - mc->width; - if (mc->x < xine.x) { - mc->x = xine.x; - mc->width = MIN(mc->width, (xine.w - xine.x)); + if (mc->geom.x + mc->geom.w >= xine.w) + mc->geom.x = xine.w - mc->geom.w; + if (mc->geom.x < xine.x) { + mc->geom.x = xine.x; + mc->geom.w = MIN(mc->geom.w, (xine.w - xine.x)); } - if (mc->y + mc->height >= xine.h) - mc->y = xine.h - mc->height; - if (mc->y < xine.y) { - mc->y = xine.y; - mc->height = MIN(mc->height, (xine.h - xine.y)); + if (mc->geom.y + mc->geom.h >= xine.h) + mc->geom.y = xine.h - mc->geom.h; + if (mc->geom.y < xine.y) { + mc->geom.y = xine.y; + mc->geom.h = MIN(mc->geom.h, (xine.h - xine.y)); } - if (mc->x != xsave || mc->y != ysave) - xu_ptr_setpos(sc->rootwin, mc->x, mc->y); + if (mc->geom.x != xsave || mc->geom.y != ysave) + xu_ptr_setpos(sc->rootwin, mc->geom.x, mc->geom.y); XClearWindow(X_Dpy, sc->menuwin); - XMoveResizeWindow(X_Dpy, sc->menuwin, mc->x, mc->y, - mc->width, mc->height); + XMoveResizeWindow(X_Dpy, sc->menuwin, mc->geom.x, mc->geom.y, + mc->geom.w, mc->geom.h); if (mc->hasprompt) { xu_xft_draw(sc, mc->dispstr, CWM_COLOR_MENU_FONT, @@ -419,7 +415,7 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq) int y = n * (sc->xftfont->height + 1) + sc->xftfont->ascent + 1; /* Stop drawing when menu doesn't fit inside the screen. */ - if (mc->y + y > xine.h) + if (mc->geom.y + y > xine.h) break; xu_xft_draw(sc, text, CWM_COLOR_MENU_FONT, 0, y); @@ -450,7 +446,7 @@ menu_draw_entry(struct menu_ctx *mc, struct menu_q *resultq, color = active ? CWM_COLOR_MENU_FG : CWM_COLOR_MENU_BG; text = mi->print[0] != '\0' ? mi->print : mi->text; XftDrawRect(sc->xftdraw, &sc->xftcolor[color], 0, - (sc->xftfont->height + 1) * entry, mc->width, + (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; xu_xft_draw(sc, text, color, @@ -506,7 +502,7 @@ menu_calc_entry(struct menu_ctx *mc, int x, int y) entry = y / (sc->xftfont->height + 1); /* in bounds? */ - if (x < 0 || x > mc->width || y < 0 || + if (x < 0 || x > mc->geom.w || y < 0 || y > (sc->xftfont->height + 1) * mc->num || entry < 0 || entry >= mc->num) entry = -1; diff --git a/mousefunc.c b/mousefunc.c index 0da19aa..3c33d2a 100644 --- a/mousefunc.c +++ b/mousefunc.c @@ -53,9 +53,7 @@ mousefunc_sweep_draw(struct client_ctx *cc) struct screen_ctx *sc = cc->sc; char s[14]; /* fits " nnnn x nnnn \0" */ - (void)snprintf(s, sizeof(s), " %4d x %-4d ", - (cc->geom.w - cc->hint.basew) / cc->hint.incw, - (cc->geom.h - cc->hint.baseh) / cc->hint.inch); + (void)snprintf(s, sizeof(s), " %4d x %-4d ", cc->dim.w, cc->dim.h); XReparentWindow(X_Dpy, sc->menuwin, cc->win, 0, 0); XMoveResizeWindow(X_Dpy, sc->menuwin, 0, 0, @@ -172,12 +170,6 @@ mousefunc_client_move(struct client_ctx *cc, union arg *arg) /* NOTREACHED */ } -void -mousefunc_client_grouptoggle(struct client_ctx *cc, union arg *arg) -{ - group_toggle_membership_enter(cc); -} - void mousefunc_menu_group(struct client_ctx *cc, union arg *arg) { @@ -194,10 +186,8 @@ mousefunc_menu_group(struct client_ctx *cc, union arg *arg) group_holds_only_hidden(gc) ? "%d: [%s]" : "%d: %s", gc->num, gc->name); } - if (TAILQ_EMPTY(&menuq)) - return; - if ((mi = menu_filter(sc, &menuq, NULL, NULL, 0, + if ((mi = menu_filter(sc, &menuq, NULL, NULL, CWM_MENU_LIST, NULL, NULL)) != NULL) { gc = (struct group_ctx *)mi->ctx; (group_holds_only_hidden(gc)) ? @@ -214,25 +204,18 @@ mousefunc_menu_unhide(struct client_ctx *cc, union arg *arg) struct client_ctx *old_cc; struct menu *mi; struct menu_q menuq; - char *wname; old_cc = client_current(); TAILQ_INIT(&menuq); TAILQ_FOREACH(cc, &sc->clientq, entry) { if (cc->flags & CLIENT_HIDDEN) { - wname = (cc->label) ? cc->label : cc->name; - if (wname == NULL) - continue; - menuq_add(&menuq, cc, "(%d) %s", - cc->group ? cc->group->num : 0, wname); + menuq_add(&menuq, cc, NULL); } } - if (TAILQ_EMPTY(&menuq)) - return; - if ((mi = menu_filter(sc, &menuq, NULL, NULL, 0, - NULL, NULL)) != NULL) { + if ((mi = menu_filter(sc, &menuq, NULL, NULL, CWM_MENU_LIST, + NULL, search_print_client)) != NULL) { cc = (struct client_ctx *)mi->ctx; client_unhide(cc); if (old_cc != NULL) @@ -254,10 +237,8 @@ mousefunc_menu_cmd(struct client_ctx *cc, union arg *arg) TAILQ_INIT(&menuq); TAILQ_FOREACH(cmd, &Conf.cmdq, entry) menuq_add(&menuq, cmd, "%s", cmd->name); - if (TAILQ_EMPTY(&menuq)) - return; - if ((mi = menu_filter(sc, &menuq, NULL, NULL, 0, + if ((mi = menu_filter(sc, &menuq, NULL, NULL, CWM_MENU_LIST, NULL, NULL)) != NULL) u_spawn(((struct cmd *)mi->ctx)->path); diff --git a/parse.y b/parse.y index d86a323..1c04e2a 100644 --- a/parse.y +++ b/parse.y @@ -156,9 +156,20 @@ main : FONTNAME STRING { free($3); YYERROR; } - conf_autogroup(conf, $2, $3); + conf_autogroup(conf, $2, NULL, $3); free($3); } + | AUTOGROUP NUMBER STRING ',' STRING { + if ($2 < 0 || $2 > 9) { + yyerror("invalid autogroup"); + free($3); + free($5); + YYERROR; + } + conf_autogroup(conf, $2, $3, $5); + free($3); + free($5); + } | IGNORE STRING { conf_ignore(conf, $2); free($2); diff --git a/search.c b/search.c index 33f2838..0d0eb1d 100644 --- a/search.c +++ b/search.c @@ -143,8 +143,9 @@ search_print_client(struct menu *mi, int list) if (list) cc->matchname = cc->name; - (void)snprintf(mi->print, sizeof(mi->print), "(%d) %c%s", - cc->group ? cc->group->num : 0, flag, cc->matchname); + (void)snprintf(mi->print, sizeof(mi->print), "(%d) %c[%s] %s", + cc->group ? cc->group->num : 0, flag, + cc->label ? cc->label : "", cc->matchname); if (!list && cc->matchname != cc->name && strlen(mi->print) < sizeof(mi->print) - 1) {