Merge branch 'linux' of git://github.com/chneukirchen/cwm into linux

Conflicts:
	calmwm.h
This commit is contained in:
Michael Weber 2013-07-27 16:34:12 +02:00
commit c5fa35ecfd
11 changed files with 282 additions and 285 deletions

View File

@ -37,6 +37,8 @@
char **cwm_argv; char **cwm_argv;
Display *X_Dpy; Display *X_Dpy;
Atom cwmh[CWMH_NITEMS];
Atom ewmh[EWMH_NITEMS];
struct screen_ctx_q Screenq = TAILQ_HEAD_INITIALIZER(Screenq); struct screen_ctx_q Screenq = TAILQ_HEAD_INITIALIZER(Screenq);
struct client_ctx_q Clientq = TAILQ_HEAD_INITIALIZER(Clientq); struct client_ctx_q Clientq = TAILQ_HEAD_INITIALIZER(Clientq);
@ -102,7 +104,6 @@ main(int argc, char **argv)
conf_path = NULL; conf_path = NULL;
} }
conf_init(&Conf); conf_init(&Conf);
if (conf_path && (parse_config(conf_path, &Conf) == -1)) if (conf_path && (parse_config(conf_path, &Conf) == -1))
warnx("config file %s has errors, not loading", conf_path); warnx("config file %s has errors, not loading", conf_path);
@ -121,8 +122,7 @@ x_init(const char *dpyname)
int i; int i;
if ((X_Dpy = XOpenDisplay(dpyname)) == NULL) if ((X_Dpy = XOpenDisplay(dpyname)) == NULL)
errx(1, "unable to open display \"%s\"", errx(1, "unable to open display \"%s\"", XDisplayName(dpyname));
XDisplayName(dpyname));
XSetErrorHandler(x_wmerrorhandler); XSetErrorHandler(x_wmerrorhandler);
XSelectInput(X_Dpy, DefaultRootWindow(X_Dpy), SubstructureRedirectMask); XSelectInput(X_Dpy, DefaultRootWindow(X_Dpy), SubstructureRedirectMask);
@ -131,7 +131,7 @@ x_init(const char *dpyname)
HasRandr = XRRQueryExtension(X_Dpy, &Randr_ev, &i); HasRandr = XRRQueryExtension(X_Dpy, &Randr_ev, &i);
xu_getatoms(); conf_atoms();
conf_cursor(&Conf); conf_cursor(&Conf);

138
calmwm.h
View File

@ -118,7 +118,7 @@ enum color {
CWM_COLOR_MENU_BG, CWM_COLOR_MENU_BG,
CWM_COLOR_MENU_FONT, CWM_COLOR_MENU_FONT,
CWM_COLOR_MENU_FONT_SEL, CWM_COLOR_MENU_FONT_SEL,
CWM_COLOR_MAX CWM_COLOR_NITEMS
}; };
struct geom { struct geom {
@ -246,7 +246,7 @@ struct screen_ctx {
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[CWM_COLOR_MAX]; XftColor xftcolor[CWM_COLOR_NITEMS];
XftDraw *xftdraw; XftDraw *xftdraw;
XftFont *xftfont; XftFont *xftfont;
int xinerama_no; int xinerama_no;
@ -281,7 +281,7 @@ struct mousebinding {
u_int button; u_int button;
#define MOUSEBIND_CTX_ROOT 0x0001 #define MOUSEBIND_CTX_ROOT 0x0001
#define MOUSEBIND_CTX_WIN 0x0002 #define MOUSEBIND_CTX_WIN 0x0002
int context; int flags;
}; };
TAILQ_HEAD(mousebinding_q, mousebinding); TAILQ_HEAD(mousebinding_q, mousebinding);
@ -321,7 +321,7 @@ struct conf {
#define CONF_SNAPDIST 0 #define CONF_SNAPDIST 0
int snapdist; int snapdist;
struct gap gap; struct gap gap;
char *color[CWM_COLOR_MAX]; char *color[CWM_COLOR_NITEMS];
char termpath[MAXPATHLEN]; char termpath[MAXPATHLEN];
char lockpath[MAXPATHLEN]; char lockpath[MAXPATHLEN];
char known_hosts[MAXPATHLEN]; char known_hosts[MAXPATHLEN];
@ -342,6 +342,53 @@ struct mwm_hints {
#define MWM_DECOR_ALL (1<<0) #define MWM_DECOR_ALL (1<<0)
#define MWM_DECOR_BORDER (1<<1) #define MWM_DECOR_BORDER (1<<1)
extern Display *X_Dpy;
extern struct screen_ctx_q Screenq;
extern struct client_ctx_q Clientq;
extern struct conf Conf;
extern char *homedir;
extern int HasRandr, Randr_ev;
enum {
WM_STATE,
WM_DELETE_WINDOW,
WM_TAKE_FOCUS,
WM_PROTOCOLS,
_MOTIF_WM_HINTS,
UTF8_STRING,
WM_CHANGE_STATE,
CWMH_NITEMS
};
enum {
_NET_SUPPORTED,
_NET_SUPPORTING_WM_CHECK,
_NET_ACTIVE_WINDOW,
_NET_CLIENT_LIST,
_NET_NUMBER_OF_DESKTOPS,
_NET_CURRENT_DESKTOP,
_NET_DESKTOP_VIEWPORT,
_NET_DESKTOP_GEOMETRY,
_NET_VIRTUAL_ROOTS,
_NET_SHOWING_DESKTOP,
_NET_DESKTOP_NAMES,
_NET_WORKAREA,
_NET_WM_NAME,
_NET_WM_DESKTOP,
_NET_CLOSE_WINDOW,
_NET_WM_STATE,
#define _NET_WM_STATES_NITEMS 2
_NET_WM_STATE_MAXIMIZED_VERT,
_NET_WM_STATE_MAXIMIZED_HORZ,
EWMH_NITEMS
};
enum {
_NET_WM_STATE_REMOVE,
_NET_WM_STATE_ADD,
_NET_WM_STATE_TOGGLE
};
extern Atom cwmh[CWMH_NITEMS];
extern Atom ewmh[EWMH_NITEMS];
__dead void usage(void); __dead void usage(void);
void client_applysizehints(struct client_ctx *); void client_applysizehints(struct client_ctx *);
@ -385,7 +432,7 @@ void group_cycle(struct screen_ctx *, int);
void group_hidetoggle(struct screen_ctx *, int); void group_hidetoggle(struct screen_ctx *, int);
void group_init(struct screen_ctx *); void group_init(struct screen_ctx *);
void group_make_autostart(struct conf *, char *, int); void group_make_autostart(struct conf *, char *, int);
void group_menu(XButtonEvent *); void group_menu(struct screen_ctx *);
void group_movetogroup(struct client_ctx *, int); void group_movetogroup(struct client_ctx *, int);
void group_only(struct screen_ctx *, int); void group_only(struct screen_ctx *, int);
void group_sticky(struct client_ctx *); void group_sticky(struct client_ctx *);
@ -428,6 +475,8 @@ void kbfunc_client_label(struct client_ctx *, union arg *);
void kbfunc_client_lower(struct client_ctx *, union arg *); void kbfunc_client_lower(struct client_ctx *, union arg *);
void kbfunc_client_maximize(struct client_ctx *, void kbfunc_client_maximize(struct client_ctx *,
union arg *); union arg *);
void kbfunc_client_moveresize(struct client_ctx *,
union arg *);
void kbfunc_client_movetogroup(struct client_ctx *, void kbfunc_client_movetogroup(struct client_ctx *,
union arg *); union arg *);
void kbfunc_client_nogroup(struct client_ctx *, void kbfunc_client_nogroup(struct client_ctx *,
@ -441,23 +490,26 @@ void kbfunc_cmdexec(struct client_ctx *, union arg *);
void kbfunc_exec(struct client_ctx *, union arg *); void kbfunc_exec(struct client_ctx *, union arg *);
void kbfunc_lock(struct client_ctx *, union arg *); void kbfunc_lock(struct client_ctx *, union arg *);
void kbfunc_menu_search(struct client_ctx *, union arg *); void kbfunc_menu_search(struct client_ctx *, union arg *);
void kbfunc_moveresize(struct client_ctx *, union arg *);
void kbfunc_quit_wm(struct client_ctx *, union arg *); void kbfunc_quit_wm(struct client_ctx *, union arg *);
void kbfunc_restart(struct client_ctx *, union arg *); void kbfunc_restart(struct client_ctx *, union arg *);
void kbfunc_ssh(struct client_ctx *, union arg *); void kbfunc_ssh(struct client_ctx *, union arg *);
void kbfunc_term(struct client_ctx *, union arg *); void kbfunc_term(struct client_ctx *, union arg *);
void kbfunc_tile(struct client_ctx *, union arg *); void kbfunc_tile(struct client_ctx *, union arg *);
void mousefunc_client_cyclegroup(struct client_ctx *,
void *);
void mousefunc_client_grouptoggle(struct client_ctx *,
void *);
void mousefunc_client_hide(struct client_ctx *, void *);
void mousefunc_client_lower(struct client_ctx *, void *);
void mousefunc_client_move(struct client_ctx *, void *);
void mousefunc_client_raise(struct client_ctx *, void *);
void mousefunc_client_rcyclegroup(struct client_ctx *,
void *);
void mousefunc_client_resize(struct client_ctx *, void *);
void mousefunc_menu_cmd(struct client_ctx *, void *); void mousefunc_menu_cmd(struct client_ctx *, void *);
void mousefunc_menu_group(struct client_ctx *, void *); void mousefunc_menu_group(struct client_ctx *, void *);
void mousefunc_menu_unhide(struct client_ctx *, void *); void mousefunc_menu_unhide(struct client_ctx *, void *);
void mousefunc_window_grouptoggle(struct client_ctx *,
void *);
void mousefunc_window_hide(struct client_ctx *, void *);
void mousefunc_window_lower(struct client_ctx *, void *);
void mousefunc_window_move(struct client_ctx *, void *);
void mousefunc_window_raise(struct client_ctx *, void *);
void mousefunc_window_resize(struct client_ctx *, void *);
struct menu *menu_filter(struct screen_ctx *, struct menu_q *, struct menu *menu_filter(struct screen_ctx *, struct menu_q *,
char *, char *, int, char *, char *, int,
@ -467,8 +519,10 @@ void menuq_clear(struct menu_q *);
int parse_config(const char *, struct conf *); int parse_config(const char *, struct conf *);
void conf_atoms(void);
void conf_autogroup(struct conf *, int, char *); void conf_autogroup(struct conf *, int, char *);
void conf_bindname(struct conf *, char *, char *); void conf_bind_kbd(struct conf *, char *, char *);
int conf_bind_mouse(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 *); void conf_cmd_add(struct conf *, char *, char *);
@ -477,14 +531,12 @@ void conf_grab_kbd(Window);
void conf_grab_mouse(Window); void conf_grab_mouse(Window);
void conf_init(struct conf *); void conf_init(struct conf *);
void conf_ignore(struct conf *, char *); void conf_ignore(struct conf *, char *);
int conf_mousebind(struct conf *, char *, char *);
void conf_screen(struct screen_ctx *); void conf_screen(struct screen_ctx *);
void xev_loop(void); void xev_loop(void);
void xu_btn_grab(Window, int, u_int); void xu_btn_grab(Window, int, u_int);
void xu_btn_ungrab(Window, int, u_int); void xu_btn_ungrab(Window, int, u_int);
void xu_getatoms(void);
int xu_getprop(Window, Atom, Atom, long, u_char **); int xu_getprop(Window, Atom, Atom, long, u_char **);
int xu_get_wm_state(Window, int *); int xu_get_wm_state(Window, int *);
int xu_getstrprop(Window, Atom, char **); int xu_getstrprop(Window, Atom, char **);
@ -531,60 +583,6 @@ int xasprintf(char **, const char *, ...)
__attribute__((__format__ (printf, 2, 3))) __attribute__((__format__ (printf, 2, 3)))
__attribute__((__nonnull__ (2))); __attribute__((__nonnull__ (2)));
/* Externs */
extern Display *X_Dpy;
extern struct screen_ctx_q Screenq;
extern struct client_ctx_q Clientq;
extern struct conf Conf;
extern char *homedir;
extern int HasRandr, Randr_ev;
enum {
WM_STATE,
WM_DELETE_WINDOW,
WM_TAKE_FOCUS,
WM_PROTOCOLS,
_MOTIF_WM_HINTS,
UTF8_STRING,
WM_CHANGE_STATE,
CWMH_NITEMS
};
enum {
_NET_SUPPORTED,
_NET_SUPPORTING_WM_CHECK,
_NET_ACTIVE_WINDOW,
_NET_CLIENT_LIST,
_NET_NUMBER_OF_DESKTOPS,
_NET_CURRENT_DESKTOP,
_NET_DESKTOP_VIEWPORT,
_NET_DESKTOP_GEOMETRY,
_NET_VIRTUAL_ROOTS,
_NET_SHOWING_DESKTOP,
_NET_DESKTOP_NAMES,
_NET_WORKAREA,
_NET_WM_NAME,
_NET_WM_DESKTOP,
_NET_CLOSE_WINDOW,
_NET_WM_STATE,
#define _NET_WM_STATES_NITEMS 2
_NET_WM_STATE_MAXIMIZED_VERT,
_NET_WM_STATE_MAXIMIZED_HORZ,
EWMH_NITEMS
};
enum {
_NET_WM_STATE_REMOVE,
_NET_WM_STATE_ADD,
_NET_WM_STATE_TOGGLE
};
struct atom_ctx {
char *name;
Atom atom;
};
extern struct atom_ctx cwmh[CWMH_NITEMS];
extern struct atom_ctx ewmh[EWMH_NITEMS];
#endif /* _CALMWM_H_ */ #endif /* _CALMWM_H_ */
#define debug(x...) fprintf(stderr, x); #define debug(x...) fprintf(stderr, x);

View File

@ -529,9 +529,9 @@ client_wm_protocols(struct client_ctx *cc)
if (XGetWMProtocols(X_Dpy, cc->win, &p, &j)) { if (XGetWMProtocols(X_Dpy, cc->win, &p, &j)) {
for (i = 0; i < j; i++) { for (i = 0; i < j; i++) {
if (p[i] == cwmh[WM_DELETE_WINDOW].atom) if (p[i] == cwmh[WM_DELETE_WINDOW])
cc->xproto |= _WM_DELETE_WINDOW; cc->xproto |= _WM_DELETE_WINDOW;
else if (p[i] == cwmh[WM_TAKE_FOCUS].atom) else if (p[i] == cwmh[WM_TAKE_FOCUS])
cc->xproto |= _WM_TAKE_FOCUS; cc->xproto |= _WM_TAKE_FOCUS;
} }
XFree(p); XFree(p);
@ -546,7 +546,7 @@ client_msg(struct client_ctx *cc, Atom proto)
bzero(&cm, sizeof(cm)); bzero(&cm, sizeof(cm));
cm.type = ClientMessage; cm.type = ClientMessage;
cm.window = cc->win; cm.window = cc->win;
cm.message_type = cwmh[WM_PROTOCOLS].atom; cm.message_type = cwmh[WM_PROTOCOLS];
cm.format = 32; cm.format = 32;
cm.data.l[0] = proto; cm.data.l[0] = proto;
cm.data.l[1] = CurrentTime; cm.data.l[1] = CurrentTime;
@ -558,7 +558,7 @@ void
client_send_delete(struct client_ctx *cc) client_send_delete(struct client_ctx *cc)
{ {
if (cc->xproto & _WM_DELETE_WINDOW) if (cc->xproto & _WM_DELETE_WINDOW)
client_msg(cc, cwmh[WM_DELETE_WINDOW].atom); client_msg(cc, cwmh[WM_DELETE_WINDOW]);
else else
XKillClient(X_Dpy, cc->win); XKillClient(X_Dpy, cc->win);
} }
@ -569,7 +569,7 @@ client_setname(struct client_ctx *cc)
struct winname *wn; struct winname *wn;
char *newname; char *newname;
if (!xu_getstrprop(cc->win, ewmh[_NET_WM_NAME].atom, &newname)) if (!xu_getstrprop(cc->win, ewmh[_NET_WM_NAME], &newname))
if (!xu_getstrprop(cc->win, XA_WM_NAME, &newname)) if (!xu_getstrprop(cc->win, XA_WM_NAME, &newname))
newname = xstrdup(""); newname = xstrdup("");
@ -840,8 +840,7 @@ client_getmwmhints(struct client_ctx *cc)
{ {
struct mwm_hints *mwmh; struct mwm_hints *mwmh;
if (xu_getprop(cc->win, if (xu_getprop(cc->win, cwmh[_MOTIF_WM_HINTS], cwmh[_MOTIF_WM_HINTS],
cwmh[_MOTIF_WM_HINTS].atom, cwmh[_MOTIF_WM_HINTS].atom,
PROP_MWM_HINTS_ELEMENTS, (u_char **)&mwmh) == MWM_NUMHINTS) PROP_MWM_HINTS_ELEMENTS, (u_char **)&mwmh) == MWM_NUMHINTS)
if (mwmh->flags & MWM_HINTS_DECORATIONS && if (mwmh->flags & MWM_HINTS_DECORATIONS &&
!(mwmh->decorations & MWM_DECOR_ALL) && !(mwmh->decorations & MWM_DECOR_ALL) &&

202
conf.c
View File

@ -31,8 +31,9 @@
#include "calmwm.h" #include "calmwm.h"
static void conf_mouseunbind(struct conf *, struct mousebinding *); static const char *conf_bind_getmask(const char *, u_int *);
static void conf_unbind(struct conf *, struct keybinding *); static void conf_unbind_kbd(struct conf *, struct keybinding *);
static void conf_unbind_mouse(struct conf *, struct mousebinding *);
/* Add an command menu entry to the end of the menu */ /* Add an command menu entry to the end of the menu */
void void
@ -98,7 +99,7 @@ static char *color_binds[] = {
void void
conf_screen(struct screen_ctx *sc) conf_screen(struct screen_ctx *sc)
{ {
int i; u_int i;
XftColor xc; XftColor xc;
sc->gap = Conf.gap; sc->gap = Conf.gap;
@ -144,7 +145,7 @@ conf_screen(struct screen_ctx *sc)
static struct { static struct {
char *key; char *key;
char *func; char *func;
} kb_binds[] = { } kbd_binds[] = {
{ "CM-Return", "terminal" }, { "CM-Return", "terminal" },
{ "CM-Delete", "lock" }, { "CM-Delete", "lock" },
{ "M-question", "exec" }, { "M-question", "exec" },
@ -209,7 +210,7 @@ static struct {
{ "4-Delete", "snapdown" }, { "4-Delete", "snapdown" },
{ "4-End", "snapright" }, { "4-End", "snapright" },
}, },
m_binds[] = { mouse_binds[] = {
{ "1", "menu_unhide" }, { "1", "menu_unhide" },
{ "2", "menu_group" }, { "2", "menu_group" },
{ "3", "menu_cmd" }, { "3", "menu_cmd" },
@ -238,11 +239,11 @@ conf_init(struct conf *c)
TAILQ_INIT(&c->autostartq); TAILQ_INIT(&c->autostartq);
TAILQ_INIT(&c->mousebindingq); TAILQ_INIT(&c->mousebindingq);
for (i = 0; i < nitems(kb_binds); i++) for (i = 0; i < nitems(kbd_binds); i++)
conf_bindname(c, kb_binds[i].key, kb_binds[i].func); conf_bind_kbd(c, kbd_binds[i].key, kbd_binds[i].func);
for (i = 0; i < nitems(m_binds); i++) for (i = 0; i < nitems(mouse_binds); i++)
conf_mousebind(c, m_binds[i].key, m_binds[i].func); conf_bind_mouse(c, mouse_binds[i].key, mouse_binds[i].func);
for (i = 0; i < nitems(color_binds); i++) for (i = 0; i < nitems(color_binds); i++)
c->color[i] = xstrdup(color_binds[i]); c->color[i] = xstrdup(color_binds[i]);
@ -301,7 +302,7 @@ conf_clear(struct conf *c)
free(mb); free(mb);
} }
for (i = 0; i < CWM_COLOR_MAX; i++) for (i = 0; i < CWM_COLOR_NITEMS; i++)
free(c->color[i]); free(c->color[i]);
free(c->font); free(c->font);
@ -395,50 +396,53 @@ static struct {
{ "ssh", kbfunc_ssh, 0, {0} }, { "ssh", kbfunc_ssh, 0, {0} },
{ "terminal", kbfunc_term, 0, {0} }, { "terminal", kbfunc_term, 0, {0} },
{ "lock", kbfunc_lock, 0, {0} }, { "lock", kbfunc_lock, 0, {0} },
{ "moveup", kbfunc_moveresize, KBFLAG_NEEDCLIENT, { "moveup", kbfunc_client_moveresize, KBFLAG_NEEDCLIENT,
{.i = (CWM_UP|CWM_MOVE)} }, {.i = (CWM_UP|CWM_MOVE)} },
{ "movedown", kbfunc_moveresize, KBFLAG_NEEDCLIENT, { "movedown", kbfunc_client_moveresize, KBFLAG_NEEDCLIENT,
{.i = (CWM_DOWN|CWM_MOVE)} }, {.i = (CWM_DOWN|CWM_MOVE)} },
{ "moveright", kbfunc_moveresize, KBFLAG_NEEDCLIENT, { "moveright", kbfunc_client_moveresize, KBFLAG_NEEDCLIENT,
{.i = (CWM_RIGHT|CWM_MOVE)} }, {.i = (CWM_RIGHT|CWM_MOVE)} },
{ "moveleft", kbfunc_moveresize, KBFLAG_NEEDCLIENT, { "moveleft", kbfunc_client_moveresize, KBFLAG_NEEDCLIENT,
{.i = (CWM_LEFT|CWM_MOVE)} }, {.i = (CWM_LEFT|CWM_MOVE)} },
{ "bigmoveup", kbfunc_moveresize, KBFLAG_NEEDCLIENT, { "bigmoveup", kbfunc_client_moveresize, KBFLAG_NEEDCLIENT,
{.i = (CWM_UP|CWM_MOVE|CWM_BIGMOVE)} }, {.i = (CWM_UP|CWM_MOVE|CWM_BIGMOVE)} },
{ "bigmovedown", kbfunc_moveresize, KBFLAG_NEEDCLIENT, { "bigmovedown", kbfunc_client_moveresize, KBFLAG_NEEDCLIENT,
{.i = (CWM_DOWN|CWM_MOVE|CWM_BIGMOVE)} }, {.i = (CWM_DOWN|CWM_MOVE|CWM_BIGMOVE)} },
{ "bigmoveright", kbfunc_moveresize, KBFLAG_NEEDCLIENT, { "bigmoveright", kbfunc_client_moveresize, KBFLAG_NEEDCLIENT,
{.i = (CWM_RIGHT|CWM_MOVE|CWM_BIGMOVE)} }, {.i = (CWM_RIGHT|CWM_MOVE|CWM_BIGMOVE)} },
{ "bigmoveleft", kbfunc_moveresize, KBFLAG_NEEDCLIENT, { "bigmoveleft", kbfunc_client_moveresize, KBFLAG_NEEDCLIENT,
{.i = (CWM_LEFT|CWM_MOVE|CWM_BIGMOVE)} }, {.i = (CWM_LEFT|CWM_MOVE|CWM_BIGMOVE)} },
{ "resizeup", kbfunc_moveresize, KBFLAG_NEEDCLIENT, { "resizeup", kbfunc_client_moveresize, KBFLAG_NEEDCLIENT,
{.i = (CWM_UP|CWM_RESIZE)} }, {.i = (CWM_UP|CWM_RESIZE)} },
{ "resizedown", kbfunc_moveresize, KBFLAG_NEEDCLIENT, { "resizedown", kbfunc_client_moveresize, KBFLAG_NEEDCLIENT,
{.i = (CWM_DOWN|CWM_RESIZE)} }, {.i = (CWM_DOWN|CWM_RESIZE)} },
{ "resizeright", kbfunc_moveresize, KBFLAG_NEEDCLIENT, { "resizeright", kbfunc_client_moveresize, KBFLAG_NEEDCLIENT,
{.i = (CWM_RIGHT|CWM_RESIZE)} }, {.i = (CWM_RIGHT|CWM_RESIZE)} },
{ "resizeleft", kbfunc_moveresize, KBFLAG_NEEDCLIENT, { "resizeleft", kbfunc_client_moveresize, KBFLAG_NEEDCLIENT,
{.i = (CWM_LEFT|CWM_RESIZE)} }, {.i = (CWM_LEFT|CWM_RESIZE)} },
{ "bigresizeup", kbfunc_moveresize, KBFLAG_NEEDCLIENT, { "bigresizeup", kbfunc_client_moveresize, KBFLAG_NEEDCLIENT,
{.i = (CWM_UP|CWM_RESIZE|CWM_BIGMOVE)} }, {.i = (CWM_UP|CWM_RESIZE|CWM_BIGMOVE)} },
{ "bigresizedown", kbfunc_moveresize, KBFLAG_NEEDCLIENT, { "bigresizedown", kbfunc_client_moveresize, KBFLAG_NEEDCLIENT,
{.i = (CWM_DOWN|CWM_RESIZE|CWM_BIGMOVE)} }, {.i = (CWM_DOWN|CWM_RESIZE|CWM_BIGMOVE)} },
{ "bigresizeright", kbfunc_moveresize, KBFLAG_NEEDCLIENT, { "bigresizeright", kbfunc_client_moveresize, KBFLAG_NEEDCLIENT,
{.i = (CWM_RIGHT|CWM_RESIZE|CWM_BIGMOVE)} }, {.i = (CWM_RIGHT|CWM_RESIZE|CWM_BIGMOVE)} },
{ "bigresizeleft", kbfunc_moveresize, KBFLAG_NEEDCLIENT, { "bigresizeleft", kbfunc_client_moveresize, KBFLAG_NEEDCLIENT,
{.i = (CWM_LEFT|CWM_RESIZE|CWM_BIGMOVE)} }, {.i = (CWM_LEFT|CWM_RESIZE|CWM_BIGMOVE)} },
{ "ptrmoveup", kbfunc_moveresize, 0, {.i = (CWM_UP|CWM_PTRMOVE)} }, { "ptrmoveup", kbfunc_client_moveresize, 0,
{ "ptrmovedown", kbfunc_moveresize, 0, {.i = (CWM_DOWN|CWM_PTRMOVE)} }, {.i = (CWM_UP|CWM_PTRMOVE)} },
{ "ptrmoveleft", kbfunc_moveresize, 0, {.i = (CWM_LEFT|CWM_PTRMOVE)} }, { "ptrmovedown", kbfunc_client_moveresize, 0,
{ "ptrmoveright", kbfunc_moveresize, 0, {.i = (CWM_DOWN|CWM_PTRMOVE)} },
{ "ptrmoveleft", kbfunc_client_moveresize, 0,
{.i = (CWM_LEFT|CWM_PTRMOVE)} },
{ "ptrmoveright", kbfunc_client_moveresize, 0,
{.i = (CWM_RIGHT|CWM_PTRMOVE)} }, {.i = (CWM_RIGHT|CWM_PTRMOVE)} },
{ "bigptrmoveup", kbfunc_moveresize, 0, { "bigptrmoveup", kbfunc_client_moveresize, 0,
{.i = (CWM_UP|CWM_PTRMOVE|CWM_BIGMOVE)} }, {.i = (CWM_UP|CWM_PTRMOVE|CWM_BIGMOVE)} },
{ "bigptrmovedown", kbfunc_moveresize, 0, { "bigptrmovedown", kbfunc_client_moveresize, 0,
{.i = (CWM_DOWN|CWM_PTRMOVE|CWM_BIGMOVE)} }, {.i = (CWM_DOWN|CWM_PTRMOVE|CWM_BIGMOVE)} },
{ "bigptrmoveleft", kbfunc_moveresize, 0, { "bigptrmoveleft", kbfunc_client_moveresize, 0,
{.i = (CWM_LEFT|CWM_PTRMOVE|CWM_BIGMOVE)} }, {.i = (CWM_LEFT|CWM_PTRMOVE|CWM_BIGMOVE)} },
{ "bigptrmoveright", kbfunc_moveresize, 0, { "bigptrmoveright", kbfunc_client_moveresize, 0,
{.i = (CWM_RIGHT|CWM_PTRMOVE|CWM_BIGMOVE)} }, {.i = (CWM_RIGHT|CWM_PTRMOVE|CWM_BIGMOVE)} },
{ "htile", kbfunc_tile, KBFLAG_NEEDCLIENT, { "htile", kbfunc_tile, KBFLAG_NEEDCLIENT,
{.i = CWM_TILE_HORIZ } }, {.i = CWM_TILE_HORIZ } },
@ -459,7 +463,7 @@ static struct {
}; };
static struct { static struct {
char chr; char ch;
int mask; int mask;
} bind_mods[] = { } bind_mods[] = {
{ 'C', ControlMask }, { 'C', ControlMask },
@ -468,27 +472,35 @@ static struct {
{ 'S', ShiftMask }, { 'S', ShiftMask },
}; };
void static const char *
conf_bindname(struct conf *c, char *name, char *binding) conf_bind_getmask(const char *name, u_int *mask)
{ {
struct keybinding *current_binding; char *dash;
char *substring, *tmp; const char *ch;
u_int i; u_int i;
current_binding = xcalloc(1, sizeof(*current_binding)); *mask = 0;
if ((dash = strchr(name, '-')) == NULL)
if ((substring = strchr(name, '-')) != NULL) { return (name);
for (i = 0; i < nitems(bind_mods); i++) { for (i = 0; i < nitems(bind_mods); i++) {
if ((tmp = strchr(name, bind_mods[i].chr)) != if ((ch = strchr(name, bind_mods[i].ch)) != NULL && ch < dash)
NULL && tmp < substring) { *mask |= bind_mods[i].mask;
current_binding->modmask |= bind_mods[i].mask;
}
} }
/* skip past the modifiers */ /* Skip past modifiers. */
substring++; return (dash + 1);
} else }
substring = name;
void
conf_bind_kbd(struct conf *c, char *name, char *binding)
{
struct keybinding *current_binding;
const char *substring;
u_int i, mask;
current_binding = xcalloc(1, sizeof(*current_binding));
substring = conf_bind_getmask(name, &mask);
current_binding->modmask |= mask;
if (substring[0] == '[' && if (substring[0] == '[' &&
substring[strlen(substring)-1] == ']') { substring[strlen(substring)-1] == ']') {
@ -506,7 +518,7 @@ conf_bindname(struct conf *c, char *name, char *binding)
} }
/* We now have the correct binding, remove duplicates. */ /* We now have the correct binding, remove duplicates. */
conf_unbind(c, current_binding); conf_unbind_kbd(c, current_binding);
if (strcmp("unmap", binding) == 0) { if (strcmp("unmap", binding) == 0) {
free(current_binding); free(current_binding);
@ -533,7 +545,7 @@ conf_bindname(struct conf *c, char *name, char *binding)
} }
static void static void
conf_unbind(struct conf *c, struct keybinding *unbind) conf_unbind_kbd(struct conf *c, struct keybinding *unbind)
{ {
struct keybinding *key = NULL, *keynxt; struct keybinding *key = NULL, *keynxt;
@ -555,15 +567,17 @@ conf_unbind(struct conf *c, struct keybinding *unbind)
static struct { static struct {
char *tag; char *tag;
void (*handler)(struct client_ctx *, void *); void (*handler)(struct client_ctx *, void *);
int context; int flags;
} name_to_mousefunc[] = { } name_to_mousefunc[] = {
{ "window_move", mousefunc_window_move, MOUSEBIND_CTX_WIN }, { "window_move", mousefunc_client_move, MOUSEBIND_CTX_WIN },
{ "window_resize", mousefunc_window_resize, MOUSEBIND_CTX_WIN }, { "window_resize", mousefunc_client_resize, MOUSEBIND_CTX_WIN },
{ "window_grouptoggle", mousefunc_window_grouptoggle, { "window_grouptoggle", mousefunc_client_grouptoggle,
MOUSEBIND_CTX_WIN }, MOUSEBIND_CTX_WIN },
{ "window_lower", mousefunc_window_lower, MOUSEBIND_CTX_WIN }, { "window_lower", mousefunc_client_lower, MOUSEBIND_CTX_WIN },
{ "window_raise", mousefunc_window_raise, MOUSEBIND_CTX_WIN }, { "window_raise", mousefunc_client_raise, MOUSEBIND_CTX_WIN },
{ "window_hide", mousefunc_window_hide, MOUSEBIND_CTX_WIN }, { "window_hide", mousefunc_client_hide, MOUSEBIND_CTX_WIN },
{ "cyclegroup", mousefunc_client_cyclegroup, MOUSEBIND_CTX_ROOT },
{ "rcyclegroup", mousefunc_client_rcyclegroup, MOUSEBIND_CTX_ROOT },
{ "menu_group", mousefunc_menu_group, MOUSEBIND_CTX_ROOT }, { "menu_group", mousefunc_menu_group, MOUSEBIND_CTX_ROOT },
{ "menu_unhide", mousefunc_menu_unhide, MOUSEBIND_CTX_ROOT }, { "menu_unhide", mousefunc_menu_unhide, MOUSEBIND_CTX_ROOT },
{ "menu_cmd", mousefunc_menu_cmd, MOUSEBIND_CTX_ROOT }, { "menu_cmd", mousefunc_menu_cmd, MOUSEBIND_CTX_ROOT },
@ -574,28 +588,15 @@ static unsigned int mouse_btns[] = {
}; };
int int
conf_mousebind(struct conf *c, char *name, char *binding) conf_bind_mouse(struct conf *c, char *name, char *binding)
{ {
struct mousebinding *current_binding; struct mousebinding *current_binding;
char *substring, *tmp; const char *errstr, *substring;
u_int button; u_int button, i, mask;
const char *errstr;
u_int i;
current_binding = xcalloc(1, sizeof(*current_binding)); current_binding = xcalloc(1, sizeof(*current_binding));
substring = conf_bind_getmask(name, &mask);
if ((substring = strchr(name, '-')) != NULL) { current_binding->modmask |= mask;
for (i = 0; i < nitems(bind_mods); i++) {
if ((tmp = strchr(name, bind_mods[i].chr)) !=
NULL && tmp < substring) {
current_binding->modmask |= bind_mods[i].mask;
}
}
/* skip past the modifiers */
substring++;
} else
substring = name;
button = strtonum(substring, 1, 5, &errstr); button = strtonum(substring, 1, 5, &errstr);
if (errstr) if (errstr)
@ -613,7 +614,7 @@ conf_mousebind(struct conf *c, char *name, char *binding)
} }
/* We now have the correct binding, remove duplicates. */ /* We now have the correct binding, remove duplicates. */
conf_mouseunbind(c, current_binding); conf_unbind_mouse(c, current_binding);
if (strcmp("unmap", binding) == 0) { if (strcmp("unmap", binding) == 0) {
free(current_binding); free(current_binding);
@ -624,8 +625,8 @@ conf_mousebind(struct conf *c, char *name, char *binding)
if (strcmp(name_to_mousefunc[i].tag, binding) != 0) if (strcmp(name_to_mousefunc[i].tag, binding) != 0)
continue; continue;
current_binding->context = name_to_mousefunc[i].context;
current_binding->callback = name_to_mousefunc[i].handler; current_binding->callback = name_to_mousefunc[i].handler;
current_binding->flags = name_to_mousefunc[i].flags;
TAILQ_INSERT_TAIL(&c->mousebindingq, current_binding, entry); TAILQ_INSERT_TAIL(&c->mousebindingq, current_binding, entry);
return (1); return (1);
} }
@ -634,7 +635,7 @@ conf_mousebind(struct conf *c, char *name, char *binding)
} }
static void static void
conf_mouseunbind(struct conf *c, struct mousebinding *unbind) conf_unbind_mouse(struct conf *c, struct mousebinding *unbind)
{ {
struct mousebinding *mb = NULL, *mbnxt; struct mousebinding *mb = NULL, *mbnxt;
@ -649,7 +650,7 @@ conf_mouseunbind(struct conf *c, struct mousebinding *unbind)
} }
} }
static int cursor_binds[CF_NITEMS] = { static int cursor_binds[] = {
XC_X_cursor, /* CF_DEFAULT */ XC_X_cursor, /* CF_DEFAULT */
XC_fleur, /* CF_MOVE */ XC_fleur, /* CF_MOVE */
XC_left_ptr, /* CF_NORMAL */ XC_left_ptr, /* CF_NORMAL */
@ -672,7 +673,7 @@ conf_grab_mouse(Window win)
struct mousebinding *mb; struct mousebinding *mb;
TAILQ_FOREACH(mb, &Conf.mousebindingq, entry) { TAILQ_FOREACH(mb, &Conf.mousebindingq, entry) {
if (mb->context != MOUSEBIND_CTX_WIN) if (mb->flags != MOUSEBIND_CTX_WIN)
continue; continue;
xu_btn_grab(win, mb->modmask, mb->button); xu_btn_grab(win, mb->modmask, mb->button);
} }
@ -688,3 +689,40 @@ conf_grab_kbd(Window win)
TAILQ_FOREACH(kb, &Conf.keybindingq, entry) TAILQ_FOREACH(kb, &Conf.keybindingq, entry)
xu_key_grab(win, kb->modmask, kb->keysym); xu_key_grab(win, kb->modmask, kb->keysym);
} }
static char *cwmhints[] = {
"WM_STATE",
"WM_DELETE_WINDOW",
"WM_TAKE_FOCUS",
"WM_PROTOCOLS",
"_MOTIF_WM_HINTS",
"UTF8_STRING",
"WM_CHANGE_STATE",
};
static char *ewmhints[] = {
"_NET_SUPPORTED",
"_NET_SUPPORTING_WM_CHECK",
"_NET_ACTIVE_WINDOW",
"_NET_CLIENT_LIST",
"_NET_NUMBER_OF_DESKTOPS",
"_NET_CURRENT_DESKTOP",
"_NET_DESKTOP_VIEWPORT",
"_NET_DESKTOP_GEOMETRY",
"_NET_VIRTUAL_ROOTS",
"_NET_SHOWING_DESKTOP",
"_NET_DESKTOP_NAMES",
"_NET_WORKAREA",
"_NET_WM_NAME",
"_NET_WM_DESKTOP",
"_NET_CLOSE_WINDOW",
"_NET_WM_STATE",
"_NET_WM_STATE_MAXIMIZED_VERT",
"_NET_WM_STATE_MAXIMIZED_HORZ",
};
void
conf_atoms(void)
{
XInternAtoms(X_Dpy, cwmhints, nitems(cwmhints), False, cwmh);
XInternAtoms(X_Dpy, ewmhints, nitems(ewmhints), False, ewmh);
}

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: January 8 2013 $ .Dd $Mdocdate: June 17 2013 $
.Dt CWMRC 5 .Dt CWMRC 5
.Os .Os
.Sh NAME .Sh NAME
@ -463,6 +463,10 @@ Raise current window.
Hide current window. Hide current window.
.It window_grouptoggle .It window_grouptoggle
Toggle group membership of current window. Toggle group membership of current window.
.It cyclegroup
Forward cycle through groups.
.It rcyclegroup
Reverse cycle through groups.
.It menu_group .It menu_group
Launch group list. Launch group list.
.It menu_unhide .It menu_unhide

15
group.c
View File

@ -344,16 +344,13 @@ group_cycle(struct screen_ctx *sc, int flags)
} }
void void
group_menu(XButtonEvent *e) group_menu(struct screen_ctx *sc)
{ {
struct screen_ctx *sc;
struct group_ctx *gc; struct group_ctx *gc;
struct menu *mi; struct menu *mi;
struct menu_q menuq; struct menu_q menuq;
int i; int i;
sc = screen_fromroot(e->root);
TAILQ_INIT(&menuq); TAILQ_INIT(&menuq);
for (i = 0; i < CALMWM_NGROUPS; i++) { for (i = 0; i < CALMWM_NGROUPS; i++) {
@ -413,7 +410,7 @@ group_autogroup(struct client_ctx *cc)
if (cc->app_class == NULL || cc->app_name == NULL) if (cc->app_class == NULL || cc->app_name == NULL)
return; return;
if (xu_getprop(cc->win, ewmh[_NET_WM_DESKTOP].atom, if (xu_getprop(cc->win, ewmh[_NET_WM_DESKTOP],
XA_CARDINAL, 1, (unsigned char **)&grpno) > 0) { XA_CARDINAL, 1, (unsigned char **)&grpno) > 0) {
if (*grpno == 0xffffffff) if (*grpno == 0xffffffff)
no = 0; no = 0;
@ -480,8 +477,8 @@ group_update_names(struct screen_ctx *sc)
unsigned char *prop_ret; unsigned char *prop_ret;
int i = 0, j = 0, nstrings = 0, n = 0, setnames = 0; int i = 0, j = 0, nstrings = 0, n = 0, setnames = 0;
if ((j = xu_getprop(sc->rootwin, ewmh[_NET_DESKTOP_NAMES].atom, if ((j = xu_getprop(sc->rootwin, ewmh[_NET_DESKTOP_NAMES],
cwmh[UTF8_STRING].atom, 0xffffff, (u_char **)&prop_ret)) > 0) { cwmh[UTF8_STRING], 0xffffff, (u_char **)&prop_ret)) > 0) {
prop_ret[j - 1] = '\0'; /* paranoia */ prop_ret[j - 1] = '\0'; /* paranoia */
while (i < j) { while (i < j) {
if (prop_ret[i++] == '\0') if (prop_ret[i++] == '\0')
@ -489,8 +486,8 @@ group_update_names(struct screen_ctx *sc)
} }
} }
strings = xmalloc((nstrings < CALMWM_NGROUPS ? CALMWM_NGROUPS : strings = xcalloc((nstrings < CALMWM_NGROUPS ? CALMWM_NGROUPS :
nstrings) * sizeof(*strings)); nstrings), sizeof(*strings));
p = (char *)prop_ret; p = (char *)prop_ret;
while (n < nstrings) { while (n < nstrings) {

View File

@ -53,7 +53,7 @@ kbfunc_client_raise(struct client_ctx *cc, union arg *arg)
#define TYPEMASK (CWM_MOVE | CWM_RESIZE | CWM_PTRMOVE | CWM_SNAP) #define TYPEMASK (CWM_MOVE | CWM_RESIZE | CWM_PTRMOVE | CWM_SNAP)
#define MOVEMASK (CWM_UP | CWM_DOWN | CWM_LEFT | CWM_RIGHT) #define MOVEMASK (CWM_UP | CWM_DOWN | CWM_LEFT | CWM_RIGHT)
void void
kbfunc_moveresize(struct client_ctx *cc, union arg *arg) kbfunc_client_moveresize(struct client_ctx *cc, union arg *arg)
{ {
struct screen_ctx *sc = cc->sc; struct screen_ctx *sc = cc->sc;
int x, y, flags, amt; int x, y, flags, amt;

View File

@ -68,7 +68,7 @@ mousefunc_sweep_draw(struct client_ctx *cc)
} }
void void
mousefunc_window_resize(struct client_ctx *cc, void *arg) mousefunc_client_resize(struct client_ctx *cc, void *arg)
{ {
XEvent ev; XEvent ev;
Time ltime = 0; Time ltime = 0;
@ -125,7 +125,7 @@ mousefunc_window_resize(struct client_ctx *cc, void *arg)
} }
void void
mousefunc_window_move(struct client_ctx *cc, void *arg) mousefunc_client_move(struct client_ctx *cc, void *arg)
{ {
XEvent ev; XEvent ev;
Time ltime = 0; Time ltime = 0;
@ -177,34 +177,46 @@ mousefunc_window_move(struct client_ctx *cc, void *arg)
} }
void void
mousefunc_window_grouptoggle(struct client_ctx *cc, void *arg) mousefunc_client_grouptoggle(struct client_ctx *cc, void *arg)
{ {
group_sticky_toggle_enter(cc); group_sticky_toggle_enter(cc);
} }
void void
mousefunc_window_lower(struct client_ctx *cc, void *arg) mousefunc_client_lower(struct client_ctx *cc, void *arg)
{ {
client_ptrsave(cc); client_ptrsave(cc);
client_lower(cc); client_lower(cc);
} }
void void
mousefunc_window_raise(struct client_ctx *cc, void *arg) mousefunc_client_raise(struct client_ctx *cc, void *arg)
{ {
client_raise(cc); client_raise(cc);
} }
void void
mousefunc_window_hide(struct client_ctx *cc, void *arg) mousefunc_client_hide(struct client_ctx *cc, void *arg)
{ {
client_hide(cc); client_hide(cc);
} }
void
mousefunc_client_cyclegroup(struct client_ctx *cc, void *arg)
{
group_cycle(cc->sc, CWM_CYCLE);
}
void
mousefunc_client_rcyclegroup(struct client_ctx *cc, void *arg)
{
group_cycle(cc->sc, CWM_RCYCLE);
}
void void
mousefunc_menu_group(struct client_ctx *cc, void *arg) mousefunc_menu_group(struct client_ctx *cc, void *arg)
{ {
group_menu(arg); group_menu(cc->sc);
} }
void void

View File

@ -167,7 +167,7 @@ main : FONTNAME STRING {
free($2); free($2);
} }
| BIND STRING string { | BIND STRING string {
conf_bindname(conf, $2, $3); conf_bind_kbd(conf, $2, $3);
free($2); free($2);
free($3); free($3);
} }
@ -183,7 +183,7 @@ main : FONTNAME STRING {
conf->gap.right = $5; conf->gap.right = $5;
} }
| MOUSEBIND STRING string { | MOUSEBIND STRING string {
if (!conf_mousebind(conf, $2, $3)) { if (!conf_bind_mouse(conf, $2, $3)) {
yyerror("invalid mousebind: %s %s", $2, $3); yyerror("invalid mousebind: %s %s", $2, $3);
free($2); free($2);
free($3); free($3);
@ -616,7 +616,7 @@ parse_config(const char *filename, struct conf *xconf)
(void)strlcpy(xconf->lockpath, conf->lockpath, (void)strlcpy(xconf->lockpath, conf->lockpath,
sizeof(xconf->lockpath)); sizeof(xconf->lockpath));
for (i = 0; i < CWM_COLOR_MAX; i++) for (i = 0; i < CWM_COLOR_NITEMS; i++)
xconf->color[i] = conf->color[i]; xconf->color[i] = conf->color[i];
xconf->font = conf->font; xconf->font = conf->font;

View File

@ -209,7 +209,7 @@ xev_handle_propertynotify(XEvent *ee)
} else { } else {
TAILQ_FOREACH(sc, &Screenq, entry) { TAILQ_FOREACH(sc, &Screenq, entry) {
if (sc->rootwin == e->window) { if (sc->rootwin == e->window) {
if (e->atom == ewmh[_NET_DESKTOP_NAMES].atom) if (e->atom == ewmh[_NET_DESKTOP_NAMES])
group_update_names(sc); group_update_names(sc);
} }
} }
@ -238,12 +238,8 @@ xev_handle_buttonpress(XEvent *ee)
{ {
XButtonEvent *e = &ee->xbutton; XButtonEvent *e = &ee->xbutton;
struct client_ctx *cc, fakecc; struct client_ctx *cc, fakecc;
struct screen_ctx *sc;
struct mousebinding *mb; struct mousebinding *mb;
sc = screen_fromroot(e->root);
cc = client_find(e->window);
e->state &= ~IGNOREMODMASK; e->state &= ~IGNOREMODMASK;
TAILQ_FOREACH(mb, &Conf.mousebindingq, entry) { TAILQ_FOREACH(mb, &Conf.mousebindingq, entry) {
@ -253,13 +249,16 @@ xev_handle_buttonpress(XEvent *ee)
if (mb == NULL) if (mb == NULL)
return; return;
if (mb->context == MOUSEBIND_CTX_ROOT) { if (mb->flags == MOUSEBIND_CTX_WIN) {
if (e->window != sc->rootwin) if (((cc = client_find(e->window)) == NULL) &&
(cc = client_current()) == NULL)
return;
} else { /* (mb->flags == MOUSEBIND_CTX_ROOT) */
if (e->window != e->root)
return; return;
cc = &fakecc; cc = &fakecc;
cc->sc = screen_fromroot(e->window); cc->sc = screen_fromroot(e->window);
} else if (cc == NULL) /* (mb->context == MOUSEBIND_CTX_WIN */ }
return;
(*mb->callback)(cc, e); (*mb->callback)(cc, e);
} }
@ -349,22 +348,20 @@ xev_handle_clientmessage(XEvent *ee)
if ((cc = client_find(e->window)) == NULL) if ((cc = client_find(e->window)) == NULL)
return; return;
if (e->message_type == cwmh[WM_CHANGE_STATE].atom && if (e->message_type == cwmh[WM_CHANGE_STATE] && e->format == 32 &&
e->format == 32 && e->data.l[0] == IconicState) e->data.l[0] == IconicState)
client_hide(cc); client_hide(cc);
if (e->message_type == ewmh[_NET_CLOSE_WINDOW].atom) if (e->message_type == ewmh[_NET_CLOSE_WINDOW])
client_send_delete(cc); client_send_delete(cc);
if (e->message_type == ewmh[_NET_ACTIVE_WINDOW].atom && if (e->message_type == ewmh[_NET_ACTIVE_WINDOW] && e->format == 32) {
e->format == 32) {
old_cc = client_current(); old_cc = client_current();
if (old_cc) if (old_cc)
client_ptrsave(old_cc); client_ptrsave(old_cc);
client_ptrwarp(cc); client_ptrwarp(cc);
} }
if (e->message_type == ewmh[_NET_WM_STATE].atom && if (e->message_type == ewmh[_NET_WM_STATE] && e->format == 32)
e->format == 32)
xu_ewmh_handle_net_wm_state_msg(cc, xu_ewmh_handle_net_wm_state_msg(cc,
e->data.l[0], e->data.l[1], e->data.l[2]); e->data.l[0], e->data.l[1], e->data.l[2]);
} }

118
xutil.c
View File

@ -159,7 +159,7 @@ xu_get_wm_state(Window win, int *state)
{ {
long *p = NULL; long *p = NULL;
if (xu_getprop(win, cwmh[WM_STATE].atom, cwmh[WM_STATE].atom, 2L, if (xu_getprop(win, cwmh[WM_STATE], cwmh[WM_STATE], 2L,
(u_char **)&p) <= 0) (u_char **)&p) <= 0)
return (-1); return (-1);
@ -177,64 +177,16 @@ xu_set_wm_state(Window win, int state)
dat[0] = state; dat[0] = state;
dat[1] = None; dat[1] = None;
XChangeProperty(X_Dpy, win, XChangeProperty(X_Dpy, win, cwmh[WM_STATE], cwmh[WM_STATE], 32,
cwmh[WM_STATE].atom, cwmh[WM_STATE].atom, 32,
PropModeReplace, (unsigned char *)dat, 2); PropModeReplace, (unsigned char *)dat, 2);
} }
struct atom_ctx cwmh[CWMH_NITEMS] = {
{"WM_STATE", None},
{"WM_DELETE_WINDOW", None},
{"WM_TAKE_FOCUS", None},
{"WM_PROTOCOLS", None},
{"_MOTIF_WM_HINTS", None},
{"UTF8_STRING", None},
{"WM_CHANGE_STATE", None},
};
struct atom_ctx ewmh[EWMH_NITEMS] = {
{"_NET_SUPPORTED", None},
{"_NET_SUPPORTING_WM_CHECK", None},
{"_NET_ACTIVE_WINDOW", None},
{"_NET_CLIENT_LIST", None},
{"_NET_NUMBER_OF_DESKTOPS", None},
{"_NET_CURRENT_DESKTOP", None},
{"_NET_DESKTOP_VIEWPORT", None},
{"_NET_DESKTOP_GEOMETRY", None},
{"_NET_VIRTUAL_ROOTS", None},
{"_NET_SHOWING_DESKTOP", None},
{"_NET_DESKTOP_NAMES", None},
{"_NET_WORKAREA", None},
{"_NET_WM_NAME", None},
{"_NET_WM_DESKTOP", None},
{"_NET_CLOSE_WINDOW", None},
{"_NET_WM_STATE", None},
{"_NET_WM_STATE_MAXIMIZED_VERT",None},
{"_NET_WM_STATE_MAXIMIZED_HORZ",None},
};
void
xu_getatoms(void)
{
u_int i;
for (i = 0; i < nitems(cwmh); i++)
cwmh[i].atom = XInternAtom(X_Dpy, cwmh[i].name, False);
for (i = 0; i < nitems(ewmh); i++)
ewmh[i].atom = XInternAtom(X_Dpy, ewmh[i].name, False);
}
/* Root Window Properties */ /* Root Window Properties */
void void
xu_ewmh_net_supported(struct screen_ctx *sc) xu_ewmh_net_supported(struct screen_ctx *sc)
{ {
Atom atom[EWMH_NITEMS]; XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_SUPPORTED],
u_int i; XA_ATOM, 32, PropModeReplace, (unsigned char *)ewmh, EWMH_NITEMS);
for (i = 0; i < nitems(ewmh); i++)
atom[i] = ewmh[i].atom;
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_SUPPORTED].atom,
XA_ATOM, 32, PropModeReplace, (unsigned char *)atom, EWMH_NITEMS);
} }
void void
@ -243,12 +195,12 @@ xu_ewmh_net_supported_wm_check(struct screen_ctx *sc)
Window w; Window w;
w = XCreateSimpleWindow(X_Dpy, sc->rootwin, -1, -1, 1, 1, 0, 0, 0); w = XCreateSimpleWindow(X_Dpy, sc->rootwin, -1, -1, 1, 1, 0, 0, 0);
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_SUPPORTING_WM_CHECK].atom, XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_SUPPORTING_WM_CHECK],
XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1); XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1);
XChangeProperty(X_Dpy, w, ewmh[_NET_SUPPORTING_WM_CHECK].atom, XChangeProperty(X_Dpy, w, ewmh[_NET_SUPPORTING_WM_CHECK],
XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1); XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1);
XChangeProperty(X_Dpy, w, ewmh[_NET_WM_NAME].atom, XChangeProperty(X_Dpy, w, ewmh[_NET_WM_NAME],
cwmh[UTF8_STRING].atom, 8, PropModeReplace, (unsigned char *)WMNAME, cwmh[UTF8_STRING], 8, PropModeReplace, (unsigned char *)WMNAME,
strlen(WMNAME)); strlen(WMNAME));
} }
@ -257,7 +209,7 @@ xu_ewmh_net_desktop_geometry(struct screen_ctx *sc)
{ {
long geom[2] = { sc->view.w, sc->view.h }; long geom[2] = { sc->view.w, sc->view.h };
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_GEOMETRY].atom, XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_GEOMETRY],
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)geom , 2); XA_CARDINAL, 32, PropModeReplace, (unsigned char *)geom , 2);
} }
@ -274,7 +226,7 @@ xu_ewmh_net_workarea(struct screen_ctx *sc)
workareas[i][3] = sc->work.h; workareas[i][3] = sc->work.h;
} }
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_WORKAREA].atom, XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_WORKAREA],
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)workareas, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)workareas,
CALMWM_NGROUPS * 4); CALMWM_NGROUPS * 4);
} }
@ -291,10 +243,10 @@ xu_ewmh_net_client_list(struct screen_ctx *sc)
if (i == 0) if (i == 0)
return; return;
winlist = xmalloc(i * sizeof(*winlist)); winlist = xcalloc(i, sizeof(*winlist));
TAILQ_FOREACH(cc, &Clientq, entry) TAILQ_FOREACH(cc, &Clientq, entry)
winlist[j++] = cc->win; winlist[j++] = cc->win;
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_CLIENT_LIST].atom, XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_CLIENT_LIST],
XA_WINDOW, 32, PropModeReplace, (unsigned char *)winlist, i); XA_WINDOW, 32, PropModeReplace, (unsigned char *)winlist, i);
free(winlist); free(winlist);
} }
@ -302,7 +254,7 @@ xu_ewmh_net_client_list(struct screen_ctx *sc)
void void
xu_ewmh_net_active_window(struct screen_ctx *sc, Window w) xu_ewmh_net_active_window(struct screen_ctx *sc, Window w)
{ {
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_ACTIVE_WINDOW].atom, XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_ACTIVE_WINDOW],
XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1); XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1);
} }
@ -312,7 +264,7 @@ xu_ewmh_net_wm_desktop_viewport(struct screen_ctx *sc)
long viewports[2] = {0, 0}; long viewports[2] = {0, 0};
/* We don't support large desktops, so this is (0, 0). */ /* We don't support large desktops, so this is (0, 0). */
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_VIEWPORT].atom, XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_VIEWPORT],
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)viewports, 2); XA_CARDINAL, 32, PropModeReplace, (unsigned char *)viewports, 2);
} }
@ -321,7 +273,7 @@ xu_ewmh_net_wm_number_of_desktops(struct screen_ctx *sc)
{ {
long ndesks = CALMWM_NGROUPS; long ndesks = CALMWM_NGROUPS;
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_NUMBER_OF_DESKTOPS].atom, XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_NUMBER_OF_DESKTOPS],
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&ndesks, 1); XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&ndesks, 1);
} }
@ -334,7 +286,7 @@ xu_ewmh_net_showing_desktop(struct screen_ctx *sc)
* Note that when we hide all groups, or when all groups are * Note that when we hide all groups, or when all groups are
* hidden we could technically set this later on. * hidden we could technically set this later on.
*/ */
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_SHOWING_DESKTOP].atom, XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_SHOWING_DESKTOP],
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&zero, 1); XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&zero, 1);
} }
@ -342,21 +294,21 @@ void
xu_ewmh_net_virtual_roots(struct screen_ctx *sc) xu_ewmh_net_virtual_roots(struct screen_ctx *sc)
{ {
/* We don't support virtual roots, so delete if set by previous wm. */ /* We don't support virtual roots, so delete if set by previous wm. */
XDeleteProperty(X_Dpy, sc->rootwin, ewmh[_NET_VIRTUAL_ROOTS].atom); XDeleteProperty(X_Dpy, sc->rootwin, ewmh[_NET_VIRTUAL_ROOTS]);
} }
void void
xu_ewmh_net_current_desktop(struct screen_ctx *sc, long idx) xu_ewmh_net_current_desktop(struct screen_ctx *sc, long idx)
{ {
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_CURRENT_DESKTOP].atom, XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_CURRENT_DESKTOP],
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&idx, 1); XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&idx, 1);
} }
void void
xu_ewmh_net_desktop_names(struct screen_ctx *sc, char *data, int n) xu_ewmh_net_desktop_names(struct screen_ctx *sc, char *data, int n)
{ {
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_NAMES].atom, XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_NAMES],
cwmh[UTF8_STRING].atom, 8, PropModeReplace, (unsigned char *)data, n); cwmh[UTF8_STRING], 8, PropModeReplace, (unsigned char *)data, n);
} }
/* Application Window Properties */ /* Application Window Properties */
@ -369,7 +321,7 @@ xu_ewmh_net_wm_desktop(struct client_ctx *cc)
if (gc) if (gc)
no = gc->shortcut; no = gc->shortcut;
XChangeProperty(X_Dpy, cc->win, ewmh[_NET_WM_DESKTOP].atom, XChangeProperty(X_Dpy, cc->win, ewmh[_NET_WM_DESKTOP],
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&no, 1); XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&no, 1);
} }
@ -378,11 +330,11 @@ xu_ewmh_get_net_wm_state(struct client_ctx *cc, int *n)
{ {
Atom *state, *p = NULL; Atom *state, *p = NULL;
if ((*n = xu_getprop(cc->win, ewmh[_NET_WM_STATE].atom, XA_ATOM, 64L, if ((*n = xu_getprop(cc->win, ewmh[_NET_WM_STATE], XA_ATOM, 64L,
(u_char **)&p)) <= 0) (u_char **)&p)) <= 0)
return (NULL); return (NULL);
state = xmalloc(*n * sizeof(Atom)); state = xcalloc(*n, sizeof(Atom));
memcpy(state, p, *n * sizeof(Atom)); memcpy(state, p, *n * sizeof(Atom));
XFree((char *)p); XFree((char *)p);
@ -393,7 +345,7 @@ void
xu_ewmh_handle_net_wm_state_msg(struct client_ctx *cc, int action, xu_ewmh_handle_net_wm_state_msg(struct client_ctx *cc, int action,
Atom first, Atom second) Atom first, Atom second)
{ {
int i; u_int i;
static struct handlers { static struct handlers {
int atom; int atom;
int property; int property;
@ -408,8 +360,8 @@ xu_ewmh_handle_net_wm_state_msg(struct client_ctx *cc, int action,
}; };
for (i = 0; i < nitems(handlers); i++) { for (i = 0; i < nitems(handlers); i++) {
if (first != ewmh[handlers[i].atom].atom && if (first != ewmh[handlers[i].atom] &&
second != ewmh[handlers[i].atom].atom) second != ewmh[handlers[i].atom])
continue; continue;
switch (action) { switch (action) {
case _NET_WM_STATE_ADD: case _NET_WM_STATE_ADD:
@ -434,9 +386,9 @@ xu_ewmh_restore_net_wm_state(struct client_ctx *cc)
atoms = xu_ewmh_get_net_wm_state(cc, &n); atoms = xu_ewmh_get_net_wm_state(cc, &n);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
if (atoms[i] == ewmh[_NET_WM_STATE_MAXIMIZED_HORZ].atom) if (atoms[i] == ewmh[_NET_WM_STATE_MAXIMIZED_HORZ])
client_hmaximize(cc); client_hmaximize(cc);
if (atoms[i] == ewmh[_NET_WM_STATE_MAXIMIZED_VERT].atom) if (atoms[i] == ewmh[_NET_WM_STATE_MAXIMIZED_VERT])
client_vmaximize(cc); client_vmaximize(cc);
} }
free(atoms); free(atoms);
@ -449,22 +401,22 @@ xu_ewmh_set_net_wm_state(struct client_ctx *cc)
int n, i, j; int n, i, j;
oatoms = xu_ewmh_get_net_wm_state(cc, &n); oatoms = xu_ewmh_get_net_wm_state(cc, &n);
atoms = xmalloc((n + _NET_WM_STATES_NITEMS) * sizeof(Atom)); atoms = xcalloc((n + _NET_WM_STATES_NITEMS), sizeof(Atom));
for (i = j = 0; i < n; i++) { for (i = j = 0; i < n; i++) {
if (oatoms[i] != ewmh[_NET_WM_STATE_MAXIMIZED_HORZ].atom && if (oatoms[i] != ewmh[_NET_WM_STATE_MAXIMIZED_HORZ] &&
oatoms[i] != ewmh[_NET_WM_STATE_MAXIMIZED_VERT].atom) oatoms[i] != ewmh[_NET_WM_STATE_MAXIMIZED_VERT])
atoms[j++] = oatoms[i]; atoms[j++] = oatoms[i];
} }
free(oatoms); free(oatoms);
if (cc->flags & CLIENT_HMAXIMIZED) if (cc->flags & CLIENT_HMAXIMIZED)
atoms[j++] = ewmh[_NET_WM_STATE_MAXIMIZED_HORZ].atom; atoms[j++] = ewmh[_NET_WM_STATE_MAXIMIZED_HORZ];
if (cc->flags & CLIENT_VMAXIMIZED) if (cc->flags & CLIENT_VMAXIMIZED)
atoms[j++] = ewmh[_NET_WM_STATE_MAXIMIZED_VERT].atom; atoms[j++] = ewmh[_NET_WM_STATE_MAXIMIZED_VERT];
if (j > 0) if (j > 0)
XChangeProperty(X_Dpy, cc->win, ewmh[_NET_WM_STATE].atom, XChangeProperty(X_Dpy, cc->win, ewmh[_NET_WM_STATE],
XA_ATOM, 32, PropModeReplace, (unsigned char *)atoms, j); XA_ATOM, 32, PropModeReplace, (unsigned char *)atoms, j);
else else
XDeleteProperty(X_Dpy, cc->win, ewmh[_NET_WM_STATE].atom); XDeleteProperty(X_Dpy, cc->win, ewmh[_NET_WM_STATE]);
free(atoms); free(atoms);
} }