cvsimport

This commit is contained in:
okan 2012-12-19 15:21:34 +00:00
commit f77166194f
14 changed files with 310 additions and 269 deletions

View File

@ -26,6 +26,7 @@
#include <errno.h> #include <errno.h>
#include <getopt.h> #include <getopt.h>
#include <locale.h> #include <locale.h>
#include <pwd.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -48,21 +49,22 @@ struct client_ctx_q Clientq = TAILQ_HEAD_INITIALIZER(Clientq);
int HasRandr, Randr_ev; int HasRandr, Randr_ev;
struct conf Conf; struct conf Conf;
char *homedir;
static void sigchld_cb(int); static void sigchld_cb(int);
static void dpy_init(const char *); static void dpy_init(const char *);
static int x_errorhandler(Display *, XErrorEvent *); static int x_errorhandler(Display *, XErrorEvent *);
static int x_wmerrorhandler(Display *, XErrorEvent *); static int x_wmerrorhandler(Display *, XErrorEvent *);
static void x_setup(void); static void x_setup(void);
static void x_setupscreen(struct screen_ctx *, u_int);
static void x_teardown(void); static void x_teardown(void);
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
const char *conf_file = NULL; const char *conf_file = NULL;
char *display_name = NULL; char *conf_path, *display_name = NULL;
int ch; int ch;
struct passwd *pw;
if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
warnx("no locale support"); warnx("no locale support");
@ -87,15 +89,36 @@ main(int argc, char **argv)
if (signal(SIGCHLD, sigchld_cb) == SIG_ERR) if (signal(SIGCHLD, sigchld_cb) == SIG_ERR)
err(1, "signal"); err(1, "signal");
if ((homedir = getenv("HOME")) == NULL || *homedir == '\0') {
pw = getpwuid(getuid());
if (pw != NULL && pw->pw_dir != NULL && *pw->pw_dir != '\0')
homedir = pw->pw_dir;
else
homedir = "/";
}
if (conf_file == NULL)
xasprintf(&conf_path, "%s/%s", homedir, CONFFILE);
else
conf_path = xstrdup(conf_file);
if (access(conf_path, R_OK) != 0) {
if (conf_file != NULL)
warn("%s", conf_file);
free(conf_path);
conf_path = NULL;
}
dpy_init(display_name); dpy_init(display_name);
bzero(&Conf, sizeof(Conf)); conf_init(&Conf);
conf_setup(&Conf, conf_file); if (conf_path && (parse_config(conf_path, &Conf) == -1))
warnx("config file %s has errors, not loading", conf_path);
free(conf_path);
xu_getatoms(); xu_getatoms();
x_setup(); x_setup();
xev_loop(); xev_loop();
x_teardown(); x_teardown();
return (0); return (0);
@ -135,7 +158,7 @@ x_setup(void)
for (i = 0; i < ScreenCount(X_Dpy); i++) { for (i = 0; i < ScreenCount(X_Dpy); i++) {
sc = xcalloc(1, sizeof(*sc)); sc = xcalloc(1, sizeof(*sc));
x_setupscreen(sc, i); screen_init(sc, i);
TAILQ_INSERT_TAIL(&Screenq, sc, entry); TAILQ_INSERT_TAIL(&Screenq, sc, entry);
} }
@ -150,69 +173,9 @@ x_setup(void)
static void static void
x_teardown(void) x_teardown(void)
{ {
struct screen_ctx *sc;
TAILQ_FOREACH(sc, &Screenq, entry)
XFreeGC(X_Dpy, sc->gc);
XCloseDisplay(X_Dpy); XCloseDisplay(X_Dpy);
} }
static void
x_setupscreen(struct screen_ctx *sc, u_int which)
{
Window *wins, w0, w1;
XWindowAttributes winattr;
XSetWindowAttributes rootattr;
u_int nwins, i;
sc->which = which;
sc->rootwin = RootWindow(X_Dpy, sc->which);
xu_ewmh_net_supported(sc);
xu_ewmh_net_supported_wm_check(sc);
conf_gap(&Conf, sc);
screen_update_geometry(sc);
conf_color(&Conf, sc);
group_init(sc);
conf_font(&Conf, sc);
TAILQ_INIT(&sc->mruq);
/* Initialize menu window. */
menu_init(sc);
rootattr.cursor = Cursor_normal;
rootattr.event_mask = CHILDMASK|PropertyChangeMask|EnterWindowMask|
LeaveWindowMask|ColormapChangeMask|BUTTONMASK;
XChangeWindowAttributes(X_Dpy, sc->rootwin,
CWEventMask|CWCursor, &rootattr);
/* Deal with existing clients. */
XQueryTree(X_Dpy, sc->rootwin, &w0, &w1, &wins, &nwins);
for (i = 0; i < nwins; i++) {
XGetWindowAttributes(X_Dpy, wins[i], &winattr);
if (winattr.override_redirect ||
winattr.map_state != IsViewable)
continue;
(void)client_new(wins[i], sc, winattr.map_state != IsUnmapped);
}
XFree(wins);
screen_updatestackingorder(sc);
if (HasRandr)
XRRSelectInput(X_Dpy, sc->rootwin, RRScreenChangeNotifyMask);
XSync(X_Dpy, False);
}
static int static int
x_wmerrorhandler(Display *dpy, XErrorEvent *e) x_wmerrorhandler(Display *dpy, XErrorEvent *e)
{ {

View File

@ -56,15 +56,12 @@ size_t strlcat(char *, const char *, size_t);
#define CONFFILE ".cwmrc" #define CONFFILE ".cwmrc"
#define WMNAME "CWM" #define WMNAME "CWM"
#define CHILDMASK (SubstructureRedirectMask|SubstructureNotifyMask)
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
#define MOUSEMASK (BUTTONMASK|PointerMotionMask) #define MOUSEMASK (BUTTONMASK|PointerMotionMask)
#define MENUMASK (MOUSEMASK|ButtonMotionMask|ExposureMask)
#define MENUGRABMASK (MOUSEMASK|ButtonMotionMask|StructureNotifyMask)
#define KEYMASK (KeyPressMask|ExposureMask) #define KEYMASK (KeyPressMask|ExposureMask)
#define MENUMASK (BUTTONMASK|ButtonMotionMask|ExposureMask| \ #define IGNOREMODMASK (LockMask|Mod2Mask)
PointerMotionMask)
#define MENUGRABMASK (BUTTONMASK|ButtonMotionMask|StructureNotifyMask|\
PointerMotionMask)
#define SEARCHMASK (KeyPressMask|ExposureMask)
/* kb movement */ /* kb movement */
#define CWM_MOVE 0x0001 #define CWM_MOVE 0x0001
@ -96,14 +93,19 @@ union arg {
int i; int i;
}; };
enum menucolor {
CWM_COLOR_MENU_FG,
CWM_COLOR_MENU_BG,
CWM_COLOR_MENU_FONT,
CWM_COLOR_MENU_FONT_SEL,
CWM_COLOR_MENU_MAX
};
enum cwmcolor { enum cwmcolor {
CWM_COLOR_BORDER_ACTIVE, CWM_COLOR_BORDER_ACTIVE,
CWM_COLOR_BORDER_INACTIVE, CWM_COLOR_BORDER_INACTIVE,
CWM_COLOR_BORDER_GROUP, CWM_COLOR_BORDER_GROUP,
CWM_COLOR_BORDER_UNGROUP, CWM_COLOR_BORDER_UNGROUP,
CWM_COLOR_FG_MENU,
CWM_COLOR_BG_MENU,
CWM_COLOR_FONT,
CWM_COLOR_MAX CWM_COLOR_MAX
}; };
@ -139,7 +141,7 @@ struct client_ctx {
struct screen_ctx *sc; struct screen_ctx *sc;
Window win; Window win;
XSizeHints *size; XSizeHints *size;
Colormap cmap; Colormap colormap;
u_int bwidth; /* border width */ u_int bwidth; /* border width */
struct geom geom, savegeom; struct geom geom, savegeom;
struct { struct {
@ -166,16 +168,16 @@ struct client_ctx {
#define CLIENT_VMAXIMIZED 0x0004 #define CLIENT_VMAXIMIZED 0x0004
#define CLIENT_HMAXIMIZED 0x0008 #define CLIENT_HMAXIMIZED 0x0008
#define CLIENT_FREEZE 0x0010 #define CLIENT_FREEZE 0x0010
#define CLIENT_GROUP 0x0020
#define CLIENT_UNGROUP 0x0040
#define CLIENT_HIGHLIGHT (CLIENT_GROUP | CLIENT_UNGROUP)
#define CLIENT_MAXFLAGS (CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED) #define CLIENT_MAXFLAGS (CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED)
#define CLIENT_MAXIMIZED (CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED) #define CLIENT_MAXIMIZED (CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED)
int flags; int flags;
int state; int state;
int active; int active;
int stackingorder; int stackingorder;
#define CLIENT_HIGHLIGHT_GROUP 0x0001
#define CLIENT_HIGHLIGHT_UNGROUP 0x0002
int highlight;
struct winname_q nameq; struct winname_q nameq;
#define CLIENT_MAXNAMEQLEN 5 #define CLIENT_MAXNAMEQLEN 5
int nameqlen; int nameqlen;
@ -217,18 +219,19 @@ TAILQ_HEAD(autogroupwin_q, autogroupwin);
struct screen_ctx { struct screen_ctx {
TAILQ_ENTRY(screen_ctx) entry; TAILQ_ENTRY(screen_ctx) entry;
u_int which; u_int which;
Visual *visual;
Colormap colormap;
Window rootwin; Window rootwin;
Window menuwin; Window menuwin;
struct color color[CWM_COLOR_MAX]; struct color color[CWM_COLOR_MAX];
GC gc;
int cycling; int cycling;
struct geom view; /* viewable area */ struct geom view; /* viewable area */
struct geom work; /* workable area, gap-applied */ struct geom work; /* workable area, gap-applied */
struct gap gap; struct gap gap;
struct cycle_entry_q mruq; struct cycle_entry_q mruq;
XftColor xftcolor; XftColor xftcolor[CWM_COLOR_MENU_MAX];
XftDraw *xftdraw; XftDraw *xftdraw;
XftFont *font; XftFont *xftfont;
int xinerama_no; int xinerama_no;
XineramaScreenInfo *xinerama; XineramaScreenInfo *xinerama;
#define CALMWM_NGROUPS 9 #define CALMWM_NGROUPS 9
@ -266,7 +269,6 @@ TAILQ_HEAD(mousebinding_q, mousebinding);
struct cmd { struct cmd {
TAILQ_ENTRY(cmd) entry; TAILQ_ENTRY(cmd) entry;
int flags;
char image[MAXPATHLEN]; char image[MAXPATHLEN];
#define CMD_MAXLABELLEN 256 #define CMD_MAXLABELLEN 256
char label[CMD_MAXLABELLEN]; char label[CMD_MAXLABELLEN];
@ -301,8 +303,10 @@ struct conf {
int snapdist; int snapdist;
struct gap gap; struct gap gap;
struct color color[CWM_COLOR_MAX]; struct color color[CWM_COLOR_MAX];
char *menucolor[CWM_COLOR_MENU_MAX];
char termpath[MAXPATHLEN]; char termpath[MAXPATHLEN];
char lockpath[MAXPATHLEN]; char lockpath[MAXPATHLEN];
char known_hosts[MAXPATHLEN];
#define CONF_FONT "sans-serif:pixelsize=14:bold" #define CONF_FONT "sans-serif:pixelsize=14:bold"
char *font; char *font;
}; };
@ -324,7 +328,8 @@ __dead void usage(void);
void client_applysizehints(struct client_ctx *); void client_applysizehints(struct client_ctx *);
struct client_ctx *client_current(void); struct client_ctx *client_current(void);
void client_cycle(struct screen_ctx *, int); void client_cycle(struct screen_ctx *, int);
void client_cycle_leave(struct screen_ctx *, struct client_ctx *); void client_cycle_leave(struct screen_ctx *,
struct client_ctx *);
void client_delete(struct client_ctx *); void client_delete(struct client_ctx *);
void client_draw_border(struct client_ctx *); void client_draw_border(struct client_ctx *);
struct client_ctx *client_find(Window); struct client_ctx *client_find(Window);
@ -337,7 +342,6 @@ void client_lower(struct client_ctx *);
void client_map(struct client_ctx *); void client_map(struct client_ctx *);
void client_maximize(struct client_ctx *); void client_maximize(struct client_ctx *);
void client_move(struct client_ctx *); void client_move(struct client_ctx *);
void client_mtf(struct client_ctx *);
struct client_ctx *client_new(Window, struct screen_ctx *, int); struct client_ctx *client_new(Window, struct screen_ctx *, int);
void client_ptrsave(struct client_ctx *); void client_ptrsave(struct client_ctx *);
void client_ptrwarp(struct client_ctx *); void client_ptrwarp(struct client_ctx *);
@ -371,8 +375,8 @@ void search_match_client(struct menu_q *, struct menu_q *,
char *); char *);
void search_match_exec(struct menu_q *, struct menu_q *, void search_match_exec(struct menu_q *, struct menu_q *,
char *); char *);
void search_match_exec_path(struct menu_q *, struct menu_q *, void search_match_exec_path(struct menu_q *,
char *); struct menu_q *, char *);
void search_match_path_any(struct menu_q *, struct menu_q *, void search_match_path_any(struct menu_q *, struct menu_q *,
char *); char *);
void search_match_text(struct menu_q *, struct menu_q *, void search_match_text(struct menu_q *, struct menu_q *,
@ -381,6 +385,7 @@ void search_print_client(struct menu *, int);
XineramaScreenInfo *screen_find_xinerama(struct screen_ctx *, int, int); XineramaScreenInfo *screen_find_xinerama(struct screen_ctx *, int, int);
struct screen_ctx *screen_fromroot(Window); struct screen_ctx *screen_fromroot(Window);
void screen_init(struct screen_ctx *, u_int);
void screen_update_geometry(struct screen_ctx *); void screen_update_geometry(struct screen_ctx *);
void screen_updatestackingorder(struct screen_ctx *); void screen_updatestackingorder(struct screen_ctx *);
@ -436,13 +441,14 @@ struct menu *menu_filter(struct screen_ctx *, struct menu_q *,
void (*)(struct menu_q *, struct menu_q *, char *), void (*)(struct menu_q *, struct menu_q *, char *),
void (*)(struct menu *, int)); void (*)(struct menu *, int));
void menu_init(struct screen_ctx *); void menu_init(struct screen_ctx *);
void menuq_clear(struct menu_q *);
int parse_config(const char *, struct conf *); int parse_config(const char *, struct conf *);
void conf_bindname(struct conf *, char *, char *); void conf_bindname(struct conf *, char *, char *);
void conf_clear(struct conf *); void conf_clear(struct conf *);
void conf_client(struct client_ctx *); void conf_client(struct client_ctx *);
void conf_cmd_add(struct conf *, char *, char *, int); void conf_cmd_add(struct conf *, char *, char *);
void conf_color(struct conf *, struct screen_ctx *); void conf_color(struct conf *, struct screen_ctx *);
void conf_font(struct conf *, struct screen_ctx *); void conf_font(struct conf *, struct screen_ctx *);
void conf_gap(struct conf *, struct screen_ctx *); void conf_gap(struct conf *, struct screen_ctx *);
@ -450,16 +456,15 @@ void conf_grab(struct conf *, struct keybinding *);
void conf_grab_mouse(struct client_ctx *); void conf_grab_mouse(struct client_ctx *);
void conf_init(struct conf *); void conf_init(struct conf *);
void conf_mousebind(struct conf *, char *, char *); void conf_mousebind(struct conf *, char *, char *);
void conf_setup(struct conf *, const char *);
void conf_ungrab(struct conf *, struct keybinding *); void conf_ungrab(struct conf *, struct keybinding *);
int font_ascent(struct screen_ctx *); int font_ascent(struct screen_ctx *);
int font_descent(struct screen_ctx *); int font_descent(struct screen_ctx *);
void font_draw(struct screen_ctx *, const char *, int, void font_draw(struct screen_ctx *, const char *, int,
Drawable, int, int); Drawable, int, int, int);
u_int font_height(struct screen_ctx *); u_int font_height(struct screen_ctx *);
void font_init(struct screen_ctx *, const char *, void font_init(struct screen_ctx *, const char *,
const char *); const char **);
int font_width(struct screen_ctx *, const char *, int); int font_width(struct screen_ctx *, const char *, int);
void xev_loop(void); void xev_loop(void);
@ -481,6 +486,8 @@ void xu_ptr_setpos(Window, int, int);
void xu_ptr_ungrab(void); void xu_ptr_ungrab(void);
void xu_sendmsg(Window, Atom, long); void xu_sendmsg(Window, Atom, long);
void xu_setstate(struct client_ctx *, int); void xu_setstate(struct client_ctx *, int);
void xu_xorcolor(XRenderColor, XRenderColor,
XRenderColor *);
void xu_ewmh_net_supported(struct screen_ctx *); void xu_ewmh_net_supported(struct screen_ctx *);
void xu_ewmh_net_supported_wm_check(struct screen_ctx *); void xu_ewmh_net_supported_wm_check(struct screen_ctx *);
@ -493,11 +500,11 @@ void xu_ewmh_net_wm_number_of_desktops(struct screen_ctx *);
void xu_ewmh_net_showing_desktop(struct screen_ctx *); void xu_ewmh_net_showing_desktop(struct screen_ctx *);
void xu_ewmh_net_virtual_roots(struct screen_ctx *); void xu_ewmh_net_virtual_roots(struct screen_ctx *);
void xu_ewmh_net_current_desktop(struct screen_ctx *, long); void xu_ewmh_net_current_desktop(struct screen_ctx *, long);
void xu_ewmh_net_desktop_names(struct screen_ctx *, char *, int); void xu_ewmh_net_desktop_names(struct screen_ctx *, char *,
int);
void xu_ewmh_net_wm_desktop(struct client_ctx *); void xu_ewmh_net_wm_desktop(struct client_ctx *);
void u_exec(char *); void u_exec(char *);
void u_spawn(char *); void u_spawn(char *);
@ -520,8 +527,9 @@ extern Cursor Cursor_resize;
extern struct screen_ctx_q Screenq; extern struct screen_ctx_q Screenq;
extern struct client_ctx_q Clientq; extern struct client_ctx_q Clientq;
extern struct conf Conf; extern struct conf Conf;
extern char *homedir;
extern int HasXinerama, HasRandr, Randr_ev; extern int HasRandr, Randr_ev;
enum { enum {
WM_STATE, WM_STATE,

View File

@ -33,6 +33,7 @@
static struct client_ctx *client_mrunext(struct client_ctx *); static struct client_ctx *client_mrunext(struct client_ctx *);
static struct client_ctx *client_mruprev(struct client_ctx *); static struct client_ctx *client_mruprev(struct client_ctx *);
static void client_mtf(struct client_ctx *);
static void client_none(struct screen_ctx *); static void client_none(struct screen_ctx *);
static void client_placecalc(struct client_ctx *); static void client_placecalc(struct client_ctx *);
static void client_update(struct client_ctx *); static void client_update(struct client_ctx *);
@ -91,7 +92,7 @@ client_new(Window win, struct screen_ctx *sc, int mapped)
cc->geom.y = wattr.y; cc->geom.y = wattr.y;
cc->geom.w = wattr.width; cc->geom.w = wattr.width;
cc->geom.h = wattr.height; cc->geom.h = wattr.height;
cc->cmap = wattr.colormap; cc->colormap = wattr.colormap;
if (wattr.map_state != IsViewable) { if (wattr.map_state != IsViewable) {
client_placecalc(cc); client_placecalc(cc);
@ -158,7 +159,7 @@ client_delete(struct client_ctx *cc)
xu_ewmh_net_client_list(sc); xu_ewmh_net_client_list(sc);
if (_curcc == cc) if (cc == client_current())
client_none(sc); client_none(sc);
XFree(cc->size); XFree(cc->size);
@ -180,7 +181,7 @@ client_leave(struct client_ctx *cc)
struct screen_ctx *sc; struct screen_ctx *sc;
if (cc == NULL) if (cc == NULL)
cc = _curcc; cc = client_current();
if (cc == NULL) if (cc == NULL)
return; return;
@ -194,14 +195,14 @@ client_setactive(struct client_ctx *cc, int fg)
struct screen_ctx *sc; struct screen_ctx *sc;
if (cc == NULL) if (cc == NULL)
cc = _curcc; cc = client_current();
if (cc == NULL) if (cc == NULL)
return; return;
sc = cc->sc; sc = cc->sc;
if (fg) { if (fg) {
XInstallColormap(X_Dpy, cc->cmap); XInstallColormap(X_Dpy, cc->colormap);
XSetInputFocus(X_Dpy, cc->win, XSetInputFocus(X_Dpy, cc->win,
RevertToPointerRoot, CurrentTime); RevertToPointerRoot, CurrentTime);
conf_grab_mouse(cc); conf_grab_mouse(cc);
@ -214,7 +215,7 @@ client_setactive(struct client_ctx *cc, int fg)
} else } else
client_leave(cc); client_leave(cc);
if (fg && _curcc != cc) { if (fg && cc != client_current()) {
client_setactive(NULL, 0); client_setactive(NULL, 0);
_curcc = cc; _curcc = cc;
xu_ewmh_net_active_window(sc, cc->win); xu_ewmh_net_active_window(sc, cc->win);
@ -480,7 +481,7 @@ client_hide(struct client_ctx *cc)
cc->flags |= CLIENT_HIDDEN; cc->flags |= CLIENT_HIDDEN;
xu_setstate(cc, IconicState); xu_setstate(cc, IconicState);
if (cc == _curcc) if (cc == client_current())
client_none(cc->sc); client_none(cc->sc);
} }
@ -489,7 +490,6 @@ client_unhide(struct client_ctx *cc)
{ {
XMapRaised(X_Dpy, cc->win); XMapRaised(X_Dpy, cc->win);
cc->highlight = 0;
cc->flags &= ~CLIENT_HIDDEN; cc->flags &= ~CLIENT_HIDDEN;
xu_setstate(cc, NormalState); xu_setstate(cc, NormalState);
client_draw_border(cc); client_draw_border(cc);
@ -502,11 +502,11 @@ client_draw_border(struct client_ctx *cc)
unsigned long pixel; unsigned long pixel;
if (cc->active) if (cc->active)
switch (cc->highlight) { switch (cc->flags & CLIENT_HIGHLIGHT) {
case CLIENT_HIGHLIGHT_GROUP: case CLIENT_GROUP:
pixel = sc->color[CWM_COLOR_BORDER_GROUP].pixel; pixel = sc->color[CWM_COLOR_BORDER_GROUP].pixel;
break; break;
case CLIENT_HIGHLIGHT_UNGROUP: case CLIENT_UNGROUP:
pixel = sc->color[CWM_COLOR_BORDER_UNGROUP].pixel; pixel = sc->color[CWM_COLOR_BORDER_UNGROUP].pixel;
break; break;
default: default:
@ -731,19 +731,17 @@ client_placecalc(struct client_ctx *cc)
} }
} }
void static void
client_mtf(struct client_ctx *cc) client_mtf(struct client_ctx *cc)
{ {
struct screen_ctx *sc; struct screen_ctx *sc;
if (cc == NULL) if (cc == NULL)
cc = _curcc; cc = client_current();
if (cc == NULL) if (cc == NULL)
return; return;
sc = cc->sc; sc = cc->sc;
/* Move to front. */
TAILQ_REMOVE(&sc->mruq, cc, mru_entry); TAILQ_REMOVE(&sc->mruq, cc, mru_entry);
TAILQ_INSERT_HEAD(&sc->mruq, cc, mru_entry); TAILQ_INSERT_HEAD(&sc->mruq, cc, mru_entry);
} }

58
conf.c
View File

@ -36,7 +36,7 @@ static void conf_unbind(struct conf *, struct keybinding *);
/* Add an command menu entry to the end of the menu */ /* Add an command menu entry to the end of the menu */
void void
conf_cmd_add(struct conf *c, char *image, char *label, int flags) conf_cmd_add(struct conf *c, char *image, char *label)
{ {
/* "term" and "lock" have special meanings. */ /* "term" and "lock" have special meanings. */
@ -46,7 +46,6 @@ conf_cmd_add(struct conf *c, char *image, char *label, int flags)
(void)strlcpy(c->lockpath, image, sizeof(c->lockpath)); (void)strlcpy(c->lockpath, image, sizeof(c->lockpath));
else { else {
struct cmd *cmd = xmalloc(sizeof(*cmd)); struct cmd *cmd = xmalloc(sizeof(*cmd));
cmd->flags = flags;
(void)strlcpy(cmd->image, image, sizeof(cmd->image)); (void)strlcpy(cmd->image, image, sizeof(cmd->image));
(void)strlcpy(cmd->label, label, sizeof(cmd->label)); (void)strlcpy(cmd->label, label, sizeof(cmd->label));
TAILQ_INSERT_TAIL(&c->cmdq, cmd, entry); TAILQ_INSERT_TAIL(&c->cmdq, cmd, entry);
@ -62,17 +61,21 @@ conf_gap(struct conf *c, struct screen_ctx *sc)
void void
conf_font(struct conf *c, struct screen_ctx *sc) conf_font(struct conf *c, struct screen_ctx *sc)
{ {
font_init(sc, c->font, c->color[CWM_COLOR_FONT].name); font_init(sc, c->font, (const char **)c->menucolor);
} }
static struct color color_binds[] = { static char *menu_color_binds[CWM_COLOR_MENU_MAX] = {
"black", /* CWM_COLOR_MENU_FG */
"white", /* CWM_COLOR_MENU_BG */
"black", /* CWM_COLOR_MENU_FONT */
"", /* CWM_COLOR_MENU_FONT_SEL */
};
static struct color color_binds[CWM_COLOR_MAX] = {
{ "#CCCCCC", 0 }, /* CWM_COLOR_BORDER_ACTIVE */ { "#CCCCCC", 0 }, /* CWM_COLOR_BORDER_ACTIVE */
{ "#666666", 0 }, /* CWM_COLOR_BORDER_INACTIVE */ { "#666666", 0 }, /* CWM_COLOR_BORDER_INACTIVE */
{ "blue", 0 }, /* CWM_COLOR_BORDER_GROUP */ { "blue", 0 }, /* CWM_COLOR_BORDER_GROUP */
{ "red", 0 }, /* CWM_COLOR_BORDER_UNGROUP */ { "red", 0 }, /* CWM_COLOR_BORDER_UNGROUP */
{ "black", 0 }, /* CWM_COLOR_FG_MENU */
{ "white", 0 }, /* CWM_COLOR_BG_MENU */
{ "black", 0 }, /* CWM_COLOR_FONT */
}; };
void void
@ -162,7 +165,8 @@ conf_init(struct conf *c)
{ {
int i; int i;
c->flags = 0; bzero(c, sizeof(*c));
c->bwidth = CONF_BWIDTH; c->bwidth = CONF_BWIDTH;
c->mamount = CONF_MAMOUNT; c->mamount = CONF_MAMOUNT;
c->snapdist = CONF_SNAPDIST; c->snapdist = CONF_SNAPDIST;
@ -182,10 +186,16 @@ conf_init(struct conf *c)
for (i = 0; i < nitems(color_binds); i++) for (i = 0; i < nitems(color_binds); i++)
c->color[i].name = xstrdup(color_binds[i].name); c->color[i].name = xstrdup(color_binds[i].name);
for (i = 0; i < nitems(menu_color_binds); i++)
c->menucolor[i] = xstrdup(menu_color_binds[i]);
/* Default term/lock */ /* Default term/lock */
(void)strlcpy(c->termpath, "xterm", sizeof(c->termpath)); (void)strlcpy(c->termpath, "xterm", sizeof(c->termpath));
(void)strlcpy(c->lockpath, "xlock", sizeof(c->lockpath)); (void)strlcpy(c->lockpath, "xlock", sizeof(c->lockpath));
(void)snprintf(c->known_hosts, sizeof(c->known_hosts), "%s/%s",
homedir, ".ssh/known_hosts");
c->font = xstrdup(CONF_FONT); c->font = xstrdup(CONF_FONT);
} }
@ -232,38 +242,6 @@ conf_clear(struct conf *c)
free(c->font); free(c->font);
} }
void
conf_setup(struct conf *c, const char *conf_file)
{
char conf_path[MAXPATHLEN];
char *home;
struct stat sb;
int parse = 0;
conf_init(c);
if (conf_file == NULL) {
if ((home = getenv("HOME")) == NULL)
errx(1, "No HOME directory.");
(void)snprintf(conf_path, sizeof(conf_path), "%s/%s",
home, CONFFILE);
if (stat(conf_path, &sb) == 0 && (sb.st_mode & S_IFREG))
parse = 1;
} else {
if (stat(conf_file, &sb) == -1 || !(sb.st_mode & S_IFREG))
errx(1, "%s: %s", conf_file, strerror(errno));
else {
(void)strlcpy(conf_path, conf_file, sizeof(conf_path));
parse = 1;
}
}
if (parse && (parse_config(conf_path, c) == -1))
warnx("config file %s has errors, not loading", conf_path);
}
void void
conf_client(struct client_ctx *cc) conf_client(struct client_ctx *cc)
{ {

View File

@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" .\"
.Dd $Mdocdate: November 7 2012 $ .Dd $Mdocdate: November 29 2012 $
.Dt CWMRC 5 .Dt CWMRC 5
.Os .Os
.Sh NAME .Sh NAME
@ -50,6 +50,7 @@ or if their name and class properties match
and and
.Ar windowclass , .Ar windowclass ,
respectively. respectively.
The more specific last match wins.
.Ar group .Ar group
is a number between 0 and 9. is a number between 0 and 9.
If If
@ -111,6 +112,9 @@ Set the color of the active border.
.It Ic color font Ar color .It Ic color font Ar color
Set menu font color. Set menu font color.
.Pp .Pp
.It Ic color selfont Ar color
Set font color for selected menu item.
.Pp
.It Ic color groupborder Ar color .It Ic color groupborder Ar color
Set the color of the border while grouping a window. Set the color of the border while grouping a window.
.Pp .Pp

47
font.c
View File

@ -33,36 +33,52 @@
int int
font_ascent(struct screen_ctx *sc) font_ascent(struct screen_ctx *sc)
{ {
return (sc->font->ascent); return (sc->xftfont->ascent);
} }
int int
font_descent(struct screen_ctx *sc) font_descent(struct screen_ctx *sc)
{ {
return (sc->font->descent); return (sc->xftfont->descent);
} }
u_int u_int
font_height(struct screen_ctx *sc) font_height(struct screen_ctx *sc)
{ {
return (sc->font->height + 1); return (sc->xftfont->height + 1);
} }
void void
font_init(struct screen_ctx *sc, const char *name, const char *color) font_init(struct screen_ctx *sc, const char *name, const char **color)
{ {
int i;
XRenderColor c;
sc->xftdraw = XftDrawCreate(X_Dpy, sc->rootwin, sc->xftdraw = XftDrawCreate(X_Dpy, sc->rootwin,
DefaultVisual(X_Dpy, sc->which), DefaultColormap(X_Dpy, sc->which)); sc->visual, sc->colormap);
if (sc->xftdraw == NULL) if (sc->xftdraw == NULL)
errx(1, "XftDrawCreate"); errx(1, "XftDrawCreate");
if (!XftColorAllocName(X_Dpy, DefaultVisual(X_Dpy, sc->which), sc->xftfont = XftFontOpenName(X_Dpy, sc->which, name);
DefaultColormap(X_Dpy, sc->which), color, &sc->xftcolor)) if (sc->xftfont == NULL)
errx(1, "XftColorAllocName");
sc->font = XftFontOpenName(X_Dpy, sc->which, name);
if (sc->font == NULL)
errx(1, "XftFontOpenName"); errx(1, "XftFontOpenName");
for (i = 0; i < CWM_COLOR_MENU_MAX; i++) {
if (*color[i] == '\0')
break;
if (!XftColorAllocName(X_Dpy, sc->visual, sc->colormap,
color[i], &sc->xftcolor[i]))
errx(1, "XftColorAllocName");
}
if (i == CWM_COLOR_MENU_MAX)
return;
xu_xorcolor(sc->xftcolor[CWM_COLOR_MENU_BG].color,
sc->xftcolor[CWM_COLOR_MENU_FG].color, &c);
xu_xorcolor(sc->xftcolor[CWM_COLOR_MENU_FONT].color, c, &c);
if (!XftColorAllocValue(X_Dpy, sc->visual, sc->colormap,
&c, &sc->xftcolor[CWM_COLOR_MENU_FONT_SEL]))
errx(1, "XftColorAllocValue");
} }
int int
@ -70,7 +86,7 @@ font_width(struct screen_ctx *sc, const char *text, int len)
{ {
XGlyphInfo extents; XGlyphInfo extents;
XftTextExtentsUtf8(X_Dpy, sc->font, (const FcChar8*)text, XftTextExtentsUtf8(X_Dpy, sc->xftfont, (const FcChar8*)text,
len, &extents); len, &extents);
return (extents.xOff); return (extents.xOff);
@ -78,9 +94,12 @@ font_width(struct screen_ctx *sc, const char *text, int len)
void void
font_draw(struct screen_ctx *sc, const char *text, int len, font_draw(struct screen_ctx *sc, const char *text, int len,
Drawable d, int x, int y) Drawable d, int active, int x, int y)
{ {
int color;
color = active ? CWM_COLOR_MENU_FONT_SEL : CWM_COLOR_MENU_FONT;
XftDrawChange(sc->xftdraw, d); XftDrawChange(sc->xftdraw, d);
XftDrawStringUtf8(sc->xftdraw, &sc->xftcolor, sc->font, x, y, XftDrawStringUtf8(sc->xftdraw, &sc->xftcolor[color], sc->xftfont, x, y,
(const FcChar8*)text, len); (const FcChar8*)text, len);
} }

27
group.c
View File

@ -218,16 +218,14 @@ void
group_sticky_toggle_enter(struct client_ctx *cc) group_sticky_toggle_enter(struct client_ctx *cc)
{ {
struct screen_ctx *sc = cc->sc; struct screen_ctx *sc = cc->sc;
struct group_ctx *gc; struct group_ctx *gc = sc->group_active;
gc = sc->group_active;
if (gc == cc->group) { if (gc == cc->group) {
group_remove(cc); group_remove(cc);
cc->highlight = CLIENT_HIGHLIGHT_UNGROUP; cc->flags |= CLIENT_UNGROUP;
} else { } else {
group_add(gc, cc); group_add(gc, cc);
cc->highlight = CLIENT_HIGHLIGHT_GROUP; cc->flags |= CLIENT_GROUP;
} }
client_draw_border(cc); client_draw_border(cc);
@ -236,7 +234,7 @@ group_sticky_toggle_enter(struct client_ctx *cc)
void void
group_sticky_toggle_exit(struct client_ctx *cc) group_sticky_toggle_exit(struct client_ctx *cc)
{ {
cc->highlight = 0; cc->flags &= ~CLIENT_HIGHLIGHT;
client_draw_border(cc); client_draw_border(cc);
} }
@ -385,10 +383,7 @@ group_menu(XButtonEvent *e)
(gc->hidden) ? group_show(sc, gc) : group_hide(sc, gc); (gc->hidden) ? group_show(sc, gc) : group_hide(sc, gc);
cleanup: cleanup:
while ((mi = TAILQ_FIRST(&menuq)) != NULL) { menuq_clear(&menuq);
TAILQ_REMOVE(&menuq, mi, entry);
free(mi);
}
} }
void void
@ -412,7 +407,7 @@ group_autogroup(struct client_ctx *cc)
struct screen_ctx *sc = cc->sc; struct screen_ctx *sc = cc->sc;
struct autogroupwin *aw; struct autogroupwin *aw;
struct group_ctx *gc; struct group_ctx *gc;
int no = -1; int no = -1, both_match = 0;
long *grpno; long *grpno;
if (cc->app_class == NULL || cc->app_name == NULL) if (cc->app_class == NULL || cc->app_name == NULL)
@ -429,11 +424,13 @@ group_autogroup(struct client_ctx *cc)
XFree(grpno); XFree(grpno);
} else { } else {
TAILQ_FOREACH(aw, &Conf.autogroupq, entry) { TAILQ_FOREACH(aw, &Conf.autogroupq, entry) {
if (strcmp(aw->class, cc->app_class) == 0 && if (strcmp(aw->class, cc->app_class) == 0) {
(aw->name == NULL || if ((aw->name != NULL) &&
strcmp(aw->name, cc->app_name) == 0)) { (strcmp(aw->name, cc->app_name) == 0)) {
no = aw->num;
both_match = 1;
} else if (aw->name == NULL && !both_match)
no = aw->num; no = aw->num;
break;
} }
} }
} }

View File

@ -33,7 +33,6 @@
#include "calmwm.h" #include "calmwm.h"
#define KNOWN_HOSTS ".ssh/known_hosts"
#define HASH_MARKER "|1|" #define HASH_MARKER "|1|"
extern char **cwm_argv; extern char **cwm_argv;
@ -168,10 +167,7 @@ kbfunc_client_search(struct client_ctx *cc, union arg *arg)
client_ptrwarp(cc); client_ptrwarp(cc);
} }
while ((mi = TAILQ_FIRST(&menuq)) != NULL) { menuq_clear(&menuq);
TAILQ_REMOVE(&menuq, mi, entry);
free(mi);
}
} }
void void
@ -195,10 +191,7 @@ kbfunc_menu_search(struct client_ctx *cc, union arg *arg)
search_match_text, NULL)) != NULL) search_match_text, NULL)) != NULL)
u_spawn(((struct cmd *)mi->ctx)->image); u_spawn(((struct cmd *)mi->ctx)->image);
while ((mi = TAILQ_FIRST(&menuq)) != NULL) { menuq_clear(&menuq);
TAILQ_REMOVE(&menuq, mi, entry);
free(mi);
}
} }
void void
@ -320,10 +313,7 @@ kbfunc_exec(struct client_ctx *cc, union arg *arg)
out: out:
if (mi != NULL && mi->dummy) if (mi != NULL && mi->dummy)
free(mi); free(mi);
while ((mi = TAILQ_FIRST(&menuq)) != NULL) { menuq_clear(&menuq);
TAILQ_REMOVE(&menuq, mi, entry);
free(mi);
}
} }
void void
@ -333,21 +323,16 @@ kbfunc_ssh(struct client_ctx *cc, union arg *arg)
struct menu *mi; struct menu *mi;
struct menu_q menuq; struct menu_q menuq;
FILE *fp; FILE *fp;
char *buf, *lbuf, *p, *home; char *buf, *lbuf, *p;
char hostbuf[MAXHOSTNAMELEN], filename[MAXPATHLEN]; char hostbuf[MAXHOSTNAMELEN];
char cmd[256]; char cmd[256];
int l; int l;
size_t len; size_t len;
if ((home = getenv("HOME")) == NULL) if ((fp = fopen(Conf.known_hosts, "r")) == NULL) {
return; warn("kbfunc_ssh: %s", Conf.known_hosts);
l = snprintf(filename, sizeof(filename), "%s/%s", home, KNOWN_HOSTS);
if (l == -1 || l >= sizeof(filename))
return;
if ((fp = fopen(filename, "r")) == NULL)
return; return;
}
TAILQ_INIT(&menuq); TAILQ_INIT(&menuq);
lbuf = NULL; lbuf = NULL;
@ -390,10 +375,7 @@ kbfunc_ssh(struct client_ctx *cc, union arg *arg)
out: out:
if (mi != NULL && mi->dummy) if (mi != NULL && mi->dummy)
free(mi); free(mi);
while ((mi = TAILQ_FIRST(&menuq)) != NULL) { menuq_clear(&menuq);
TAILQ_REMOVE(&menuq, mi, entry);
free(mi);
}
} }
void void

97
menu.c
View File

@ -65,11 +65,13 @@ struct menu_ctx {
static struct menu *menu_handle_key(XEvent *, struct menu_ctx *, static struct menu *menu_handle_key(XEvent *, struct menu_ctx *,
struct menu_q *, struct menu_q *); struct menu_q *, struct menu_q *);
static void menu_handle_move(XEvent *, struct menu_ctx *, static void menu_handle_move(XEvent *, struct menu_ctx *,
struct screen_ctx *); struct screen_ctx *, struct menu_q *);
static struct menu *menu_handle_release(XEvent *, struct menu_ctx *, static struct menu *menu_handle_release(XEvent *, struct menu_ctx *,
struct screen_ctx *, struct menu_q *); struct screen_ctx *, struct menu_q *);
static void menu_draw(struct screen_ctx *, struct menu_ctx *, static void menu_draw(struct screen_ctx *, struct menu_ctx *,
struct menu_q *, struct menu_q *); struct menu_q *, struct menu_q *);
static void menu_draw_entry(struct screen_ctx *, struct menu_ctx *,
struct menu_q *, int, int);
static int menu_calc_entry(struct screen_ctx *, struct menu_ctx *, static int menu_calc_entry(struct screen_ctx *, struct menu_ctx *,
int, int); int, int);
static int menu_keycode(XKeyEvent *, enum ctltype *, static int menu_keycode(XKeyEvent *, enum ctltype *,
@ -78,20 +80,10 @@ static int menu_keycode(XKeyEvent *, enum ctltype *,
void void
menu_init(struct screen_ctx *sc) menu_init(struct screen_ctx *sc)
{ {
XGCValues gv;
sc->menuwin = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, 1, 1, sc->menuwin = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, 1, 1,
Conf.bwidth, Conf.bwidth,
sc->color[CWM_COLOR_FG_MENU].pixel, sc->xftcolor[CWM_COLOR_MENU_FG].pixel,
sc->color[CWM_COLOR_BG_MENU].pixel); sc->xftcolor[CWM_COLOR_MENU_BG].pixel);
gv.foreground =
sc->color[CWM_COLOR_FG_MENU].pixel^sc->color[CWM_COLOR_BG_MENU].pixel;
gv.background = sc->color[CWM_COLOR_BG_MENU].pixel;
gv.function = GXxor;
sc->gc = XCreateGC(X_Dpy, sc->menuwin,
GCForeground|GCBackground|GCFunction, &gv);
} }
struct menu * struct menu *
@ -174,7 +166,7 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, char *prompt,
menu_draw(sc, &mc, menuq, &resultq); menu_draw(sc, &mc, menuq, &resultq);
break; break;
case MotionNotify: case MotionNotify:
menu_handle_move(&e, &mc, sc); menu_handle_move(&e, &mc, sc, &resultq);
break; break;
case ButtonRelease: case ButtonRelease:
if ((mi = menu_handle_release(&e, &mc, sc, &resultq)) if ((mi = menu_handle_release(&e, &mc, sc, &resultq))
@ -223,10 +215,7 @@ menu_complete_path(struct menu_ctx *mc)
strlcpy(path, mi->text, sizeof(mi->text)); strlcpy(path, mi->text, sizeof(mi->text));
} }
while ((mi = TAILQ_FIRST(&menuq)) != NULL) { menuq_clear(&menuq);
TAILQ_REMOVE(&menuq, mi, entry);
free(mi);
}
if (path[0] != '\0') if (path[0] != '\0')
snprintf(mr->text, sizeof(mr->text), "%s \"%s\"", snprintf(mr->text, sizeof(mr->text), "%s \"%s\"",
@ -442,8 +431,8 @@ menu_draw(struct screen_ctx *sc, struct menu_ctx *mc, struct menu_q *menuq,
mc->width, mc->height); mc->width, mc->height);
if (mc->hasprompt) { if (mc->hasprompt) {
font_draw(sc, mc->dispstr, strlen(mc->dispstr), sc->menuwin, font_draw(sc, mc->dispstr, strlen(mc->dispstr), sc->menuwin, 0,
0, font_ascent(sc) + 1); 0, font_ascent(sc));
n = 1; n = 1;
} else } else
n = 0; n = 0;
@ -458,34 +447,61 @@ menu_draw(struct screen_ctx *sc, struct menu_ctx *mc, struct menu_q *menuq,
break; break;
font_draw(sc, text, MIN(strlen(text), MENU_MAXENTRY), font_draw(sc, text, MIN(strlen(text), MENU_MAXENTRY),
sc->menuwin, 0, y); sc->menuwin, 0, 0, y);
n++; n++;
} }
if (mc->hasprompt && n > 1 && (mc->searchstr[0] != '\0')) {
if (mc->hasprompt && n > 1 && (mc->searchstr[0] != '\0')) mc->entry = 1;
XFillRectangle(X_Dpy, sc->menuwin, sc->gc, menu_draw_entry(sc, mc, resultq, mc->entry, 1);
0, font_height(sc), mc->width, font_height(sc)); }
if (mc->noresult)
XFillRectangle(X_Dpy, sc->menuwin, sc->gc,
0, 0, mc->width, font_height(sc));
} }
static void static void
menu_handle_move(XEvent *e, struct menu_ctx *mc, struct screen_ctx *sc) menu_draw_entry(struct screen_ctx *sc, struct menu_ctx *mc,
struct menu_q *resultq, int entry, int active)
{
struct menu *mi;
char *text;
int color, i = 0;
if (mc->hasprompt)
i = 1;
TAILQ_FOREACH(mi, resultq, resultentry)
if (entry == i++)
break;
if (mi == NULL)
return;
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,
font_height(sc) * entry, mc->width,
font_height(sc) + font_descent(sc));
font_draw(sc, text, strlen(text), sc->menuwin, active,
0, font_height(sc) * entry + font_ascent(sc) + 1);
}
static void
menu_handle_move(XEvent *e, struct menu_ctx *mc, struct screen_ctx *sc,
struct menu_q *resultq)
{ {
mc->prev = mc->entry; mc->prev = mc->entry;
mc->entry = menu_calc_entry(sc, mc, e->xbutton.x, e->xbutton.y); mc->entry = menu_calc_entry(sc, mc, e->xbutton.x, e->xbutton.y);
if (mc->prev == mc->entry)
return;
if (mc->prev != -1) if (mc->prev != -1)
XFillRectangle(X_Dpy, sc->menuwin, sc->gc, 0, menu_draw_entry(sc, mc, resultq, mc->prev, 0);
font_height(sc) * mc->prev, mc->width, font_height(sc));
if (mc->entry != -1) { if (mc->entry != -1) {
(void)xu_ptr_regrab(MENUGRABMASK, Cursor_normal); (void)xu_ptr_regrab(MENUGRABMASK, Cursor_normal);
XFillRectangle(X_Dpy, sc->menuwin, sc->gc, 0, menu_draw_entry(sc, mc, resultq, mc->entry, 1);
font_height(sc) * mc->entry, mc->width, font_height(sc));
} else } else
(void)xu_ptr_regrab(MENUGRABMASK, Cursor_default); (void)xu_ptr_regrab(MENUGRABMASK, Cursor_default);
if (mc->hasprompt)
menu_draw_entry(sc, mc, resultq, 1, 1);
} }
static struct menu * static struct menu *
@ -519,7 +535,7 @@ menu_calc_entry(struct screen_ctx *sc, struct menu_ctx *mc, int x, int y)
entry = y / font_height(sc); entry = y / font_height(sc);
/* in bounds? */ /* in bounds? */
if (x <= 0 || x > mc->width || y <= 0 || if (x < 0 || x > mc->width || y < 0 ||
y > font_height(sc) * mc->num || entry < 0 || entry >= mc->num) y > font_height(sc) * mc->num || entry < 0 || entry >= mc->num)
entry = -1; entry = -1;
@ -613,3 +629,14 @@ menu_keycode(XKeyEvent *ev, enum ctltype *ctl, char *chr)
return (0); return (0);
} }
void
menuq_clear(struct menu_q *mq)
{
struct menu *mi;
while ((mi = TAILQ_FIRST(mq)) != NULL) {
TAILQ_REMOVE(mq, mi, entry);
free(mi);
}
}

View File

@ -68,9 +68,9 @@ mousefunc_sweep_draw(struct client_ctx *cc)
XMoveResizeWindow(X_Dpy, sc->menuwin, 0, 0, width, font_height(sc) * 2); XMoveResizeWindow(X_Dpy, sc->menuwin, 0, 0, width, font_height(sc) * 2);
XMapWindow(X_Dpy, sc->menuwin); XMapWindow(X_Dpy, sc->menuwin);
XClearWindow(X_Dpy, sc->menuwin); XClearWindow(X_Dpy, sc->menuwin);
font_draw(sc, cc->name, strlen(cc->name), sc->menuwin, font_draw(sc, cc->name, strlen(cc->name), sc->menuwin, 0,
2, font_ascent(sc) + 1); 2, font_ascent(sc) + 1);
font_draw(sc, asize, strlen(asize), sc->menuwin, font_draw(sc, asize, strlen(asize), sc->menuwin, 0,
width / 2 - width_size / 2, font_height(sc) + font_ascent(sc) + 1); width / 2 - width_size / 2, font_height(sc) + font_ascent(sc) + 1);
} }
@ -250,12 +250,8 @@ mousefunc_menu_unhide(struct client_ctx *cc, void *arg)
if (old_cc != NULL) if (old_cc != NULL)
client_ptrsave(old_cc); client_ptrsave(old_cc);
client_ptrwarp(cc); client_ptrwarp(cc);
} else { } else
while ((mi = TAILQ_FIRST(&menuq)) != NULL) { menuq_clear(&menuq);
TAILQ_REMOVE(&menuq, mi, entry);
free(mi);
}
}
} }
void void
@ -280,8 +276,5 @@ mousefunc_menu_cmd(struct client_ctx *cc, void *arg)
if (mi != NULL) if (mi != NULL)
u_spawn(((struct cmd *)mi->ctx)->image); u_spawn(((struct cmd *)mi->ctx)->image);
else else
while ((mi = TAILQ_FIRST(&menuq)) != NULL) { menuq_clear(&menuq);
TAILQ_REMOVE(&menuq, mi, entry);
free(mi);
}
} }

25
parse.y
View File

@ -75,7 +75,8 @@ typedef struct {
%token COLOR SNAPDIST %token COLOR SNAPDIST
%token ACTIVEBORDER INACTIVEBORDER %token ACTIVEBORDER INACTIVEBORDER
%token GROUPBORDER UNGROUPBORDER %token GROUPBORDER UNGROUPBORDER
%token MENUBG MENUFG FONTCOLOR %token MENUBG MENUFG
%token FONTCOLOR FONTSELCOLOR
%token ERROR %token ERROR
%token <v.string> STRING %token <v.string> STRING
%token <v.number> NUMBER %token <v.number> NUMBER
@ -127,7 +128,7 @@ main : FONTNAME STRING {
conf->snapdist = $2; conf->snapdist = $2;
} }
| COMMAND STRING string { | COMMAND STRING string {
conf_cmd_add(conf, $3, $2, 0); conf_cmd_add(conf, $3, $2);
free($2); free($2);
free($3); free($3);
} }
@ -188,16 +189,20 @@ colors : ACTIVEBORDER STRING {
conf->color[CWM_COLOR_BORDER_UNGROUP].name = $2; conf->color[CWM_COLOR_BORDER_UNGROUP].name = $2;
} }
| MENUBG STRING { | MENUBG STRING {
free(conf->color[CWM_COLOR_BG_MENU].name); free(conf->menucolor[CWM_COLOR_MENU_BG]);
conf->color[CWM_COLOR_BG_MENU].name = $2; conf->menucolor[CWM_COLOR_MENU_BG] = $2;
} }
| MENUFG STRING { | MENUFG STRING {
free(conf->color[CWM_COLOR_FG_MENU].name); free(conf->menucolor[CWM_COLOR_MENU_FG]);
conf->color[CWM_COLOR_FG_MENU].name = $2; conf->menucolor[CWM_COLOR_MENU_FG] = $2;
} }
| FONTCOLOR STRING { | FONTCOLOR STRING {
free(conf->color[CWM_COLOR_FONT].name); free(conf->menucolor[CWM_COLOR_MENU_FONT]);
conf->color[CWM_COLOR_FONT].name = $2; conf->menucolor[CWM_COLOR_MENU_FONT] = $2;
}
| FONTSELCOLOR STRING {
free(conf->menucolor[CWM_COLOR_MENU_FONT_SEL]);
conf->menucolor[CWM_COLOR_MENU_FONT_SEL] = $2;
} }
; ;
%% %%
@ -249,6 +254,7 @@ lookup(char *s)
{ "mousebind", MOUSEBIND}, { "mousebind", MOUSEBIND},
{ "moveamount", MOVEAMOUNT}, { "moveamount", MOVEAMOUNT},
{ "no", NO}, { "no", NO},
{ "selfont", FONTSELCOLOR},
{ "snapdist", SNAPDIST}, { "snapdist", SNAPDIST},
{ "sticky", STICKY}, { "sticky", STICKY},
{ "ungroupborder", UNGROUPBORDER}, { "ungroupborder", UNGROUPBORDER},
@ -577,6 +583,9 @@ parse_config(const char *filename, struct conf *xconf)
for (i = 0; i < CWM_COLOR_MAX; i++) for (i = 0; i < CWM_COLOR_MAX; i++)
xconf->color[i].name = conf->color[i].name; xconf->color[i].name = conf->color[i].name;
for (i = 0; i < CWM_COLOR_MENU_MAX; i++)
xconf->menucolor[i] = conf->menucolor[i];
xconf->font = conf->font; xconf->font = conf->font;
} }

View File

@ -32,6 +32,63 @@
static void screen_init_xinerama(struct screen_ctx *); static void screen_init_xinerama(struct screen_ctx *);
void
screen_init(struct screen_ctx *sc, u_int which)
{
Window *wins, w0, w1;
XWindowAttributes winattr;
XSetWindowAttributes rootattr;
u_int nwins, i;
sc->which = which;
sc->visual = DefaultVisual(X_Dpy, sc->which);
sc->colormap = DefaultColormap(X_Dpy, sc->which);
sc->rootwin = RootWindow(X_Dpy, sc->which);
xu_ewmh_net_supported(sc);
xu_ewmh_net_supported_wm_check(sc);
conf_gap(&Conf, sc);
screen_update_geometry(sc);
conf_color(&Conf, sc);
group_init(sc);
conf_font(&Conf, sc);
TAILQ_INIT(&sc->mruq);
menu_init(sc);
rootattr.cursor = Cursor_normal;
rootattr.event_mask = SubstructureRedirectMask|SubstructureNotifyMask|
PropertyChangeMask|EnterWindowMask|LeaveWindowMask|
ColormapChangeMask|BUTTONMASK;
XChangeWindowAttributes(X_Dpy, sc->rootwin,
CWEventMask|CWCursor, &rootattr);
/* Deal with existing clients. */
XQueryTree(X_Dpy, sc->rootwin, &w0, &w1, &wins, &nwins);
for (i = 0; i < nwins; i++) {
XGetWindowAttributes(X_Dpy, wins[i], &winattr);
if (winattr.override_redirect ||
winattr.map_state != IsViewable)
continue;
(void)client_new(wins[i], sc, winattr.map_state != IsUnmapped);
}
XFree(wins);
screen_updatestackingorder(sc);
if (HasRandr)
XRRSelectInput(X_Dpy, sc->rootwin, RRScreenChangeNotifyMask);
XSync(X_Dpy, False);
}
struct screen_ctx * struct screen_ctx *
screen_fromroot(Window rootwin) screen_fromroot(Window rootwin)
{ {

View File

@ -241,8 +241,7 @@ xev_handle_buttonpress(XEvent *ee)
sc = screen_fromroot(e->root); sc = screen_fromroot(e->root);
cc = client_find(e->window); cc = client_find(e->window);
/* Ignore caps lock and numlock */ e->state &= ~IGNOREMODMASK;
e->state &= ~(Mod2Mask | LockMask);
TAILQ_FOREACH(mb, &Conf.mousebindingq, entry) { TAILQ_FOREACH(mb, &Conf.mousebindingq, entry) {
if (e->button == mb->button && e->state == mb->modmask) if (e->button == mb->button && e->state == mb->modmask)
@ -283,8 +282,7 @@ xev_handle_keypress(XEvent *ee)
keysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 0); keysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 0);
skeysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 1); skeysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 1);
/* we don't care about caps lock and numlock here */ e->state &= ~IGNOREMODMASK;
e->state &= ~(LockMask | Mod2Mask);
TAILQ_FOREACH(kb, &Conf.keybindingq, entry) { TAILQ_FOREACH(kb, &Conf.keybindingq, entry) {
if (keysym != kb->keysym && skeysym == kb->keysym) if (keysym != kb->keysym && skeysym == kb->keysym)

12
xutil.c
View File

@ -422,11 +422,19 @@ xu_getcolor(struct screen_ctx *sc, char *name)
{ {
XColor color, tmp; XColor color, tmp;
if (!XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, sc->which), if (!XAllocNamedColor(X_Dpy, sc->colormap, name, &color, &tmp)) {
name, &color, &tmp)) {
warnx("XAllocNamedColor error: '%s'", name); warnx("XAllocNamedColor error: '%s'", name);
return (0); return (0);
} }
return (color.pixel); return (color.pixel);
} }
void
xu_xorcolor(XRenderColor a, XRenderColor b, XRenderColor *r)
{
r->red = a.red ^ b.red;
r->green = a.green ^ b.green;
r->blue = a.blue ^ b.blue;
r->alpha = 0xffff;
}