mirror of
https://github.com/leahneukirchen/cwm.git
synced 2023-08-10 21:13:12 +03:00
cvsimport
This commit is contained in:
commit
5515a365ba
4
Makefile
4
Makefile
|
@ -7,11 +7,11 @@ PREFIX= /usr/local
|
|||
|
||||
SRCS= calmwm.c screen.c xmalloc.c client.c menu.c \
|
||||
search.c util.c xutil.c conf.c xevents.c group.c \
|
||||
kbfunc.c mousefunc.c font.c parse.y
|
||||
kbfunc.c mousefunc.c parse.y
|
||||
|
||||
OBJS= calmwm.o screen.o xmalloc.o client.o menu.o \
|
||||
search.o util.o xutil.o conf.o xevents.o group.o \
|
||||
kbfunc.o mousefunc.o font.o strlcpy.o strlcat.o y.tab.o \
|
||||
kbfunc.o mousefunc.o strlcpy.o strlcat.o y.tab.o \
|
||||
strtonum.o fgetln.o
|
||||
|
||||
CPPFLAGS+= `pkg-config --cflags fontconfig x11 xft xinerama xrandr`
|
||||
|
|
10
calmwm.c
10
calmwm.c
|
@ -144,7 +144,6 @@ dpy_init(const char *dpyname)
|
|||
static void
|
||||
x_setup(void)
|
||||
{
|
||||
struct keybinding *kb;
|
||||
int i;
|
||||
|
||||
Cursor_default = XCreateFontCursor(X_Dpy, XC_X_cursor);
|
||||
|
@ -155,13 +154,6 @@ x_setup(void)
|
|||
|
||||
for (i = 0; i < ScreenCount(X_Dpy); i++)
|
||||
screen_init(i);
|
||||
|
||||
/*
|
||||
* XXX key grabs weren't done before, since Screenq was empty,
|
||||
* do them here for now (this needs changing).
|
||||
*/
|
||||
TAILQ_FOREACH(kb, &Conf.keybindingq, entry)
|
||||
conf_grab(&Conf, kb);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -181,7 +173,7 @@ x_wmerrorhandler(Display *dpy, XErrorEvent *e)
|
|||
static int
|
||||
x_errorhandler(Display *dpy, XErrorEvent *e)
|
||||
{
|
||||
#if DEBUG
|
||||
#ifdef DEBUG
|
||||
char msg[80], number[80], req[80];
|
||||
|
||||
XGetErrorText(X_Dpy, e->error_code, msg, sizeof(msg));
|
||||
|
|
95
calmwm.h
95
calmwm.h
|
@ -97,20 +97,16 @@ union arg {
|
|||
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 bordercolor {
|
||||
enum color {
|
||||
CWM_COLOR_BORDER_ACTIVE,
|
||||
CWM_COLOR_BORDER_INACTIVE,
|
||||
CWM_COLOR_BORDER_GROUP,
|
||||
CWM_COLOR_BORDER_UNGROUP,
|
||||
CWM_COLOR_BORDER_MAX
|
||||
CWM_COLOR_MENU_FG,
|
||||
CWM_COLOR_MENU_BG,
|
||||
CWM_COLOR_MENU_FONT,
|
||||
CWM_COLOR_MENU_FONT_SEL,
|
||||
CWM_COLOR_MAX
|
||||
};
|
||||
|
||||
struct geom {
|
||||
|
@ -133,6 +129,11 @@ struct winname {
|
|||
};
|
||||
TAILQ_HEAD(winname_q, winname);
|
||||
|
||||
enum wm_protocols {
|
||||
_WM_DELETE_WINDOW = 0x0001,
|
||||
_WM_TAKE_FOCUS = 0x0002,
|
||||
};
|
||||
|
||||
struct client_ctx {
|
||||
TAILQ_ENTRY(client_ctx) entry;
|
||||
TAILQ_ENTRY(client_ctx) group_entry;
|
||||
|
@ -159,9 +160,7 @@ struct client_ctx {
|
|||
int x; /* x position */
|
||||
int y; /* y position */
|
||||
} ptr;
|
||||
#define CLIENT_PROTO_DELETE 0x0001
|
||||
#define CLIENT_PROTO_TAKEFOCUS 0x0002
|
||||
int xproto;
|
||||
enum wm_protocols xproto;
|
||||
#define CLIENT_HIDDEN 0x0001
|
||||
#define CLIENT_IGNORE 0x0002
|
||||
#define CLIENT_VMAXIMIZED 0x0004
|
||||
|
@ -222,13 +221,12 @@ struct screen_ctx {
|
|||
Colormap colormap;
|
||||
Window rootwin;
|
||||
Window menuwin;
|
||||
unsigned long color[CWM_COLOR_BORDER_MAX];
|
||||
int cycling;
|
||||
struct geom view; /* viewable area */
|
||||
struct geom work; /* workable area, gap-applied */
|
||||
struct gap gap;
|
||||
struct cycle_entry_q mruq;
|
||||
XftColor xftcolor[CWM_COLOR_MENU_MAX];
|
||||
XftColor xftcolor[CWM_COLOR_MAX];
|
||||
XftDraw *xftdraw;
|
||||
XftFont *xftfont;
|
||||
int xinerama_no;
|
||||
|
@ -247,8 +245,8 @@ struct keybinding {
|
|||
TAILQ_ENTRY(keybinding) entry;
|
||||
void (*callback)(struct client_ctx *, union arg *);
|
||||
union arg argument;
|
||||
int modmask;
|
||||
int keysym;
|
||||
u_int modmask;
|
||||
KeySym keysym;
|
||||
int keycode;
|
||||
#define KBFLAG_NEEDCLIENT 0x0001
|
||||
int flags;
|
||||
|
@ -259,8 +257,8 @@ TAILQ_HEAD(keybinding_q, keybinding);
|
|||
struct mousebinding {
|
||||
TAILQ_ENTRY(mousebinding) entry;
|
||||
void (*callback)(struct client_ctx *, void *);
|
||||
int modmask;
|
||||
int button;
|
||||
u_int modmask;
|
||||
u_int button;
|
||||
#define MOUSEBIND_CTX_ROOT 0x0001
|
||||
#define MOUSEBIND_CTX_WIN 0x0002
|
||||
int context;
|
||||
|
@ -302,8 +300,7 @@ struct conf {
|
|||
#define CONF_SNAPDIST 0
|
||||
int snapdist;
|
||||
struct gap gap;
|
||||
char *color[CWM_COLOR_BORDER_MAX];
|
||||
char *menucolor[CWM_COLOR_MENU_MAX];
|
||||
char *color[CWM_COLOR_MAX];
|
||||
char termpath[MAXPATHLEN];
|
||||
char lockpath[MAXPATHLEN];
|
||||
char known_hosts[MAXPATHLEN];
|
||||
|
@ -343,7 +340,7 @@ void client_lower(struct client_ctx *);
|
|||
void client_map(struct client_ctx *);
|
||||
void client_maximize(struct client_ctx *);
|
||||
void client_move(struct client_ctx *);
|
||||
struct client_ctx *client_new(Window, struct screen_ctx *, int);
|
||||
struct client_ctx *client_init(Window, struct screen_ctx *, int);
|
||||
void client_ptrsave(struct client_ctx *);
|
||||
void client_ptrwarp(struct client_ctx *);
|
||||
void client_raise(struct client_ctx *);
|
||||
|
@ -360,7 +357,6 @@ void client_warp(struct client_ctx *);
|
|||
|
||||
void group_alltoggle(struct screen_ctx *);
|
||||
void group_autogroup(struct client_ctx *);
|
||||
void group_client_delete(struct client_ctx *);
|
||||
void group_cycle(struct screen_ctx *, int);
|
||||
void group_hidetoggle(struct screen_ctx *, int);
|
||||
void group_init(struct screen_ctx *);
|
||||
|
@ -442,7 +438,6 @@ struct menu *menu_filter(struct screen_ctx *, struct menu_q *,
|
|||
char *, char *, int,
|
||||
void (*)(struct menu_q *, struct menu_q *, char *),
|
||||
void (*)(struct menu *, int));
|
||||
void menu_init(struct screen_ctx *);
|
||||
void menuq_clear(struct menu_q *);
|
||||
|
||||
int parse_config(const char *, struct conf *);
|
||||
|
@ -452,24 +447,12 @@ void conf_bindname(struct conf *, char *, char *);
|
|||
void conf_clear(struct conf *);
|
||||
void conf_client(struct client_ctx *);
|
||||
void conf_cmd_add(struct conf *, char *, char *);
|
||||
void conf_color(struct conf *, struct screen_ctx *);
|
||||
void conf_font(struct conf *, struct screen_ctx *);
|
||||
void conf_gap(struct conf *, struct screen_ctx *);
|
||||
void conf_grab(struct conf *, struct keybinding *);
|
||||
void conf_grab_mouse(struct client_ctx *);
|
||||
void conf_grab_kbd(Window);
|
||||
void conf_grab_mouse(Window);
|
||||
void conf_init(struct conf *);
|
||||
void conf_ignore(struct conf *, char *);
|
||||
void conf_mousebind(struct conf *, char *, char *);
|
||||
void conf_ungrab(struct conf *, struct keybinding *);
|
||||
|
||||
int font_ascent(struct screen_ctx *);
|
||||
int font_descent(struct screen_ctx *);
|
||||
void font_draw(struct screen_ctx *, const char *, int,
|
||||
Drawable, int, int, int);
|
||||
u_int font_height(struct screen_ctx *);
|
||||
void font_init(struct screen_ctx *, const char *,
|
||||
const char **);
|
||||
int font_width(struct screen_ctx *, const char *, int);
|
||||
int conf_mousebind(struct conf *, char *, char *);
|
||||
void conf_screen(struct screen_ctx *);
|
||||
|
||||
void xev_loop(void);
|
||||
|
||||
|
@ -477,21 +460,21 @@ void xu_btn_grab(Window, int, u_int);
|
|||
void xu_btn_ungrab(Window, int, u_int);
|
||||
void xu_configure(struct client_ctx *);
|
||||
void xu_getatoms(void);
|
||||
unsigned long xu_getcolor(struct screen_ctx *, char *);
|
||||
int xu_getprop(Window, Atom, Atom, long, u_char **);
|
||||
int xu_get_wm_state(Window, int *);
|
||||
int xu_getstrprop(Window, Atom, char **);
|
||||
void xu_key_grab(Window, int, int);
|
||||
void xu_key_ungrab(Window, int, int);
|
||||
void xu_key_grab(Window, u_int, KeySym);
|
||||
void xu_ptr_getpos(Window, int *, int *);
|
||||
int xu_ptr_grab(Window, int, Cursor);
|
||||
int xu_ptr_regrab(int, Cursor);
|
||||
int xu_ptr_grab(Window, u_int, Cursor);
|
||||
int xu_ptr_regrab(u_int, Cursor);
|
||||
void xu_ptr_setpos(Window, int, int);
|
||||
void xu_ptr_ungrab(void);
|
||||
void xu_sendmsg(Window, Atom, long);
|
||||
void xu_sendmsg(Window, Atom, Atom);
|
||||
void xu_set_wm_state(Window win, int);
|
||||
void xu_xorcolor(XRenderColor, XRenderColor,
|
||||
XRenderColor *);
|
||||
void xu_xft_draw(struct screen_ctx *, const char *,
|
||||
int, int, int);
|
||||
int xu_xft_width(XftFont *, const char *, int);
|
||||
void xu_xorcolor(XftColor, XftColor, XftColor *);
|
||||
|
||||
void xu_ewmh_net_supported(struct screen_ctx *);
|
||||
void xu_ewmh_net_supported_wm_check(struct screen_ctx *);
|
||||
|
@ -508,6 +491,11 @@ void xu_ewmh_net_desktop_names(struct screen_ctx *, char *,
|
|||
int);
|
||||
|
||||
void xu_ewmh_net_wm_desktop(struct client_ctx *);
|
||||
Atom *xu_ewmh_get_net_wm_state(struct client_ctx *, int *);
|
||||
void xu_ewmh_handle_net_wm_state_msg(struct client_ctx *,
|
||||
int, Atom , Atom);
|
||||
void xu_ewmh_set_net_wm_state(struct client_ctx *);
|
||||
void xu_ewmh_restore_net_wm_state(struct client_ctx *);
|
||||
|
||||
void u_exec(char *);
|
||||
void u_spawn(char *);
|
||||
|
@ -542,6 +530,7 @@ enum {
|
|||
WM_PROTOCOLS,
|
||||
_MOTIF_WM_HINTS,
|
||||
UTF8_STRING,
|
||||
WM_CHANGE_STATE,
|
||||
CWMH_NITEMS
|
||||
};
|
||||
enum {
|
||||
|
@ -559,8 +548,18 @@ enum {
|
|||
_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;
|
||||
|
|
48
client.c
48
client.c
|
@ -36,7 +36,7 @@ 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_placecalc(struct client_ctx *);
|
||||
static void client_update(struct client_ctx *);
|
||||
static void client_wm_protocols(struct client_ctx *);
|
||||
static void client_getmwmhints(struct client_ctx *);
|
||||
static int client_inbound(struct client_ctx *, int, int);
|
||||
|
||||
|
@ -55,7 +55,7 @@ client_find(Window win)
|
|||
}
|
||||
|
||||
struct client_ctx *
|
||||
client_new(Window win, struct screen_ctx *sc, int mapped)
|
||||
client_init(Window win, struct screen_ctx *sc, int mapped)
|
||||
{
|
||||
struct client_ctx *cc;
|
||||
XClassHint xch;
|
||||
|
@ -132,7 +132,8 @@ client_new(Window win, struct screen_ctx *sc, int mapped)
|
|||
|
||||
xu_ewmh_net_client_list(sc);
|
||||
|
||||
client_update(cc);
|
||||
client_wm_protocols(cc);
|
||||
xu_ewmh_restore_net_wm_state(cc);
|
||||
|
||||
if (mapped)
|
||||
group_autogroup(cc);
|
||||
|
@ -149,13 +150,10 @@ client_delete(struct client_ctx *cc)
|
|||
struct screen_ctx *sc = cc->sc;
|
||||
struct winname *wn;
|
||||
|
||||
group_client_delete(cc);
|
||||
|
||||
XGrabServer(X_Dpy);
|
||||
cc->state = WithdrawnState;
|
||||
xu_set_wm_state(cc->win, cc->state);
|
||||
XRemoveFromSaveSet(X_Dpy, cc->win);
|
||||
|
||||
XSync(X_Dpy, False);
|
||||
XUngrabServer(X_Dpy);
|
||||
|
||||
|
@ -164,6 +162,9 @@ client_delete(struct client_ctx *cc)
|
|||
|
||||
xu_ewmh_net_client_list(sc);
|
||||
|
||||
if (cc->group != NULL)
|
||||
TAILQ_REMOVE(&cc->group->clients, cc, group_entry);
|
||||
|
||||
if (cc == client_current())
|
||||
client_none(sc);
|
||||
|
||||
|
@ -212,7 +213,7 @@ client_setactive(struct client_ctx *cc, int fg)
|
|||
XInstallColormap(X_Dpy, cc->colormap);
|
||||
XSetInputFocus(X_Dpy, cc->win,
|
||||
RevertToPointerRoot, CurrentTime);
|
||||
conf_grab_mouse(cc);
|
||||
conf_grab_mouse(cc->win);
|
||||
/*
|
||||
* If we're in the middle of alt-tabbing, don't change
|
||||
* the order please.
|
||||
|
@ -301,6 +302,7 @@ client_maximize(struct client_ctx *cc)
|
|||
|
||||
resize:
|
||||
client_resize(cc, 0);
|
||||
xu_ewmh_set_net_wm_state(cc);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -341,6 +343,7 @@ client_vmaximize(struct client_ctx *cc)
|
|||
|
||||
resize:
|
||||
client_resize(cc, 0);
|
||||
xu_ewmh_set_net_wm_state(cc);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -381,6 +384,7 @@ client_hmaximize(struct client_ctx *cc)
|
|||
|
||||
resize:
|
||||
client_resize(cc, 0);
|
||||
xu_ewmh_set_net_wm_state(cc);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -389,6 +393,7 @@ client_resize(struct client_ctx *cc, int reset)
|
|||
if (reset) {
|
||||
cc->flags &= ~CLIENT_MAXIMIZED;
|
||||
cc->bwidth = Conf.bwidth;
|
||||
xu_ewmh_set_net_wm_state(cc);
|
||||
}
|
||||
|
||||
client_draw_border(cc);
|
||||
|
@ -480,46 +485,43 @@ client_draw_border(struct client_ctx *cc)
|
|||
if (cc->active)
|
||||
switch (cc->flags & CLIENT_HIGHLIGHT) {
|
||||
case CLIENT_GROUP:
|
||||
pixel = sc->color[CWM_COLOR_BORDER_GROUP];
|
||||
pixel = sc->xftcolor[CWM_COLOR_BORDER_GROUP].pixel;
|
||||
break;
|
||||
case CLIENT_UNGROUP:
|
||||
pixel = sc->color[CWM_COLOR_BORDER_UNGROUP];
|
||||
pixel = sc->xftcolor[CWM_COLOR_BORDER_UNGROUP].pixel;
|
||||
break;
|
||||
default:
|
||||
pixel = sc->color[CWM_COLOR_BORDER_ACTIVE];
|
||||
pixel = sc->xftcolor[CWM_COLOR_BORDER_ACTIVE].pixel;
|
||||
break;
|
||||
}
|
||||
else
|
||||
pixel = sc->color[CWM_COLOR_BORDER_INACTIVE];
|
||||
pixel = sc->xftcolor[CWM_COLOR_BORDER_INACTIVE].pixel;
|
||||
|
||||
XSetWindowBorderWidth(X_Dpy, cc->win, cc->bwidth);
|
||||
XSetWindowBorder(X_Dpy, cc->win, pixel);
|
||||
}
|
||||
|
||||
static void
|
||||
client_update(struct client_ctx *cc)
|
||||
client_wm_protocols(struct client_ctx *cc)
|
||||
{
|
||||
Atom *p;
|
||||
int i;
|
||||
long n;
|
||||
int i, j;
|
||||
|
||||
if ((n = xu_getprop(cc->win, cwmh[WM_PROTOCOLS].atom,
|
||||
XA_ATOM, 20L, (u_char **)&p)) <= 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
if (XGetWMProtocols(X_Dpy, cc->win, &p, &j)) {
|
||||
for (i = 0; i < j; i++) {
|
||||
if (p[i] == cwmh[WM_DELETE_WINDOW].atom)
|
||||
cc->xproto |= CLIENT_PROTO_DELETE;
|
||||
cc->xproto |= _WM_DELETE_WINDOW;
|
||||
else if (p[i] == cwmh[WM_TAKE_FOCUS].atom)
|
||||
cc->xproto |= CLIENT_PROTO_TAKEFOCUS;
|
||||
|
||||
cc->xproto |= _WM_TAKE_FOCUS;
|
||||
}
|
||||
XFree(p);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
client_send_delete(struct client_ctx *cc)
|
||||
{
|
||||
if (cc->xproto & CLIENT_PROTO_DELETE)
|
||||
if (cc->xproto & _WM_DELETE_WINDOW)
|
||||
xu_sendmsg(cc->win,
|
||||
cwmh[WM_PROTOCOLS].atom, cwmh[WM_DELETE_WINDOW].atom);
|
||||
else
|
||||
|
|
176
conf.c
176
conf.c
|
@ -84,39 +84,63 @@ conf_ignore(struct conf *c, char *val)
|
|||
TAILQ_INSERT_TAIL(&c->ignoreq, wm, entry);
|
||||
}
|
||||
|
||||
void
|
||||
conf_gap(struct conf *c, struct screen_ctx *sc)
|
||||
{
|
||||
sc->gap = c->gap;
|
||||
}
|
||||
|
||||
void
|
||||
conf_font(struct conf *c, struct screen_ctx *sc)
|
||||
{
|
||||
font_init(sc, c->font, (const char **)c->menucolor);
|
||||
}
|
||||
|
||||
static char *menu_color_binds[CWM_COLOR_MENU_MAX] = {
|
||||
static char *color_binds[CWM_COLOR_MAX] = {
|
||||
"#CCCCCC", /* CWM_COLOR_BORDER_ACTIVE */
|
||||
"#666666", /* CWM_COLOR_BORDER_INACTIVE */
|
||||
"blue", /* CWM_COLOR_BORDER_GROUP */
|
||||
"red", /* CWM_COLOR_BORDER_UNGROUP */
|
||||
"black", /* CWM_COLOR_MENU_FG */
|
||||
"white", /* CWM_COLOR_MENU_BG */
|
||||
"black", /* CWM_COLOR_MENU_FONT */
|
||||
"", /* CWM_COLOR_MENU_FONT_SEL */
|
||||
};
|
||||
|
||||
static char *color_binds[CWM_COLOR_BORDER_MAX] = {
|
||||
"#CCCCCC", /* CWM_COLOR_BORDER_ACTIVE */
|
||||
"#666666", /* CWM_COLOR_BORDER_INACTIVE */
|
||||
"blue", /* CWM_COLOR_BORDER_GROUP */
|
||||
"red", /* CWM_COLOR_BORDER_UNGROUP */
|
||||
};
|
||||
|
||||
void
|
||||
conf_color(struct conf *c, struct screen_ctx *sc)
|
||||
conf_screen(struct screen_ctx *sc)
|
||||
{
|
||||
int i;
|
||||
XftColor xc;
|
||||
|
||||
for (i = 0; i < CWM_COLOR_BORDER_MAX; i++)
|
||||
sc->color[i] = xu_getcolor(sc, c->color[i]);
|
||||
sc->gap = Conf.gap;
|
||||
|
||||
sc->xftfont = XftFontOpenName(X_Dpy, sc->which, Conf.font);
|
||||
if (sc->xftfont == NULL)
|
||||
errx(1, "XftFontOpenName");
|
||||
|
||||
for (i = 0; i < CWM_COLOR_MAX; i++) {
|
||||
if (*Conf.color[i] == '\0')
|
||||
break;
|
||||
if (XftColorAllocName(X_Dpy, sc->visual, sc->colormap,
|
||||
Conf.color[i], &xc)) {
|
||||
sc->xftcolor[i] = xc;
|
||||
XftColorFree(X_Dpy, sc->visual, sc->colormap, &xc);
|
||||
} else {
|
||||
warnx("XftColorAllocName: '%s'", Conf.color[i]);
|
||||
XftColorAllocName(X_Dpy, sc->visual, sc->colormap,
|
||||
color_binds[i], &sc->xftcolor[i]);
|
||||
}
|
||||
}
|
||||
if (i == CWM_COLOR_MAX)
|
||||
return;
|
||||
|
||||
xu_xorcolor(sc->xftcolor[CWM_COLOR_MENU_BG],
|
||||
sc->xftcolor[CWM_COLOR_MENU_FG], &xc);
|
||||
xu_xorcolor(sc->xftcolor[CWM_COLOR_MENU_FONT], xc, &xc);
|
||||
if (!XftColorAllocValue(X_Dpy, sc->visual, sc->colormap,
|
||||
&xc.color, &sc->xftcolor[CWM_COLOR_MENU_FONT_SEL]))
|
||||
warnx("XftColorAllocValue: '%s'", Conf.color[i]);
|
||||
|
||||
sc->menuwin = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, 1, 1,
|
||||
Conf.bwidth,
|
||||
sc->xftcolor[CWM_COLOR_MENU_FG].pixel,
|
||||
sc->xftcolor[CWM_COLOR_MENU_BG].pixel);
|
||||
|
||||
sc->xftdraw = XftDrawCreate(X_Dpy, sc->menuwin,
|
||||
sc->visual, sc->colormap);
|
||||
if (sc->xftdraw == NULL)
|
||||
errx(1, "XftDrawCreate");
|
||||
|
||||
conf_grab_kbd(sc->rootwin);
|
||||
}
|
||||
|
||||
static struct {
|
||||
|
@ -195,7 +219,7 @@ m_binds[] = {
|
|||
void
|
||||
conf_init(struct conf *c)
|
||||
{
|
||||
int i;
|
||||
u_int i;
|
||||
|
||||
bzero(c, sizeof(*c));
|
||||
|
||||
|
@ -218,9 +242,6 @@ conf_init(struct conf *c)
|
|||
for (i = 0; i < nitems(color_binds); i++)
|
||||
c->color[i] = xstrdup(color_binds[i]);
|
||||
|
||||
for (i = 0; i < nitems(menu_color_binds); i++)
|
||||
c->menucolor[i] = xstrdup(menu_color_binds[i]);
|
||||
|
||||
/* Default term/lock */
|
||||
(void)strlcpy(c->termpath, "xterm", sizeof(c->termpath));
|
||||
(void)strlcpy(c->lockpath, "xlock", sizeof(c->lockpath));
|
||||
|
@ -268,7 +289,7 @@ conf_clear(struct conf *c)
|
|||
free(mb);
|
||||
}
|
||||
|
||||
for (i = 0; i < CWM_COLOR_BORDER_MAX; i++)
|
||||
for (i = 0; i < CWM_COLOR_MAX; i++)
|
||||
free(c->color[i]);
|
||||
|
||||
free(c->font);
|
||||
|
@ -413,37 +434,6 @@ static struct {
|
|||
{.i = CWM_TILE_VERT } },
|
||||
};
|
||||
|
||||
/*
|
||||
* The following two functions are used when grabbing and ungrabbing keys for
|
||||
* bindings
|
||||
*/
|
||||
|
||||
/*
|
||||
* Grab key combination on all screens and add to the global queue
|
||||
*/
|
||||
void
|
||||
conf_grab(struct conf *c, struct keybinding *kb)
|
||||
{
|
||||
extern struct screen_ctx_q Screenq;
|
||||
struct screen_ctx *sc;
|
||||
|
||||
TAILQ_FOREACH(sc, &Screenq, entry)
|
||||
xu_key_grab(sc->rootwin, kb->modmask, kb->keysym);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ungrab key combination from all screens and remove from global queue
|
||||
*/
|
||||
void
|
||||
conf_ungrab(struct conf *c, struct keybinding *kb)
|
||||
{
|
||||
extern struct screen_ctx_q Screenq;
|
||||
struct screen_ctx *sc;
|
||||
|
||||
TAILQ_FOREACH(sc, &Screenq, entry)
|
||||
xu_key_ungrab(sc->rootwin, kb->modmask, kb->keysym);
|
||||
}
|
||||
|
||||
static struct {
|
||||
char chr;
|
||||
int mask;
|
||||
|
@ -459,7 +449,7 @@ conf_bindname(struct conf *c, char *name, char *binding)
|
|||
{
|
||||
struct keybinding *current_binding;
|
||||
char *substring, *tmp;
|
||||
int i;
|
||||
u_int i;
|
||||
|
||||
current_binding = xcalloc(1, sizeof(*current_binding));
|
||||
|
||||
|
@ -507,7 +497,6 @@ conf_bindname(struct conf *c, char *name, char *binding)
|
|||
current_binding->flags = name_to_kbfunc[i].flags;
|
||||
current_binding->argument = name_to_kbfunc[i].argument;
|
||||
current_binding->argtype |= ARG_INT;
|
||||
conf_grab(c, current_binding);
|
||||
TAILQ_INSERT_TAIL(&c->keybindingq, current_binding, entry);
|
||||
return;
|
||||
}
|
||||
|
@ -516,7 +505,6 @@ conf_bindname(struct conf *c, char *name, char *binding)
|
|||
current_binding->flags = 0;
|
||||
current_binding->argument.c = xstrdup(binding);
|
||||
current_binding->argtype |= ARG_CHAR;
|
||||
conf_grab(c, current_binding);
|
||||
TAILQ_INSERT_TAIL(&c->keybindingq, current_binding, entry);
|
||||
}
|
||||
|
||||
|
@ -532,7 +520,6 @@ conf_unbind(struct conf *c, struct keybinding *unbind)
|
|||
if ((key->keycode != 0 && key->keysym == NoSymbol &&
|
||||
key->keycode == unbind->keycode) ||
|
||||
key->keysym == unbind->keysym) {
|
||||
conf_ungrab(c, key);
|
||||
TAILQ_REMOVE(&c->keybindingq, key, entry);
|
||||
if (key->argtype & ARG_CHAR)
|
||||
free(key->argument.c);
|
||||
|
@ -558,13 +545,16 @@ static struct {
|
|||
{ "menu_cmd", mousefunc_menu_cmd, MOUSEBIND_CTX_ROOT },
|
||||
};
|
||||
|
||||
void
|
||||
static unsigned int mouse_btns[] = { Button1, Button2, Button3 };
|
||||
|
||||
int
|
||||
conf_mousebind(struct conf *c, char *name, char *binding)
|
||||
{
|
||||
struct mousebinding *current_binding;
|
||||
char *substring, *tmp;
|
||||
u_int button;
|
||||
const char *errstr;
|
||||
int i;
|
||||
u_int i;
|
||||
|
||||
current_binding = xcalloc(1, sizeof(*current_binding));
|
||||
|
||||
|
@ -581,16 +571,27 @@ conf_mousebind(struct conf *c, char *name, char *binding)
|
|||
} else
|
||||
substring = name;
|
||||
|
||||
current_binding->button = strtonum(substring, 1, 3, &errstr);
|
||||
button = strtonum(substring, 1, 3, &errstr);
|
||||
if (errstr)
|
||||
warnx("number of buttons is %s: %s", errstr, substring);
|
||||
warnx("button number is %s: %s", errstr, substring);
|
||||
|
||||
for (i = 0; i < nitems(mouse_btns); i++) {
|
||||
if (button == mouse_btns[i]) {
|
||||
current_binding->button = button;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!current_binding->button || errstr) {
|
||||
free(current_binding);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* We now have the correct binding, remove duplicates. */
|
||||
conf_mouseunbind(c, current_binding);
|
||||
|
||||
if (strcmp("unmap", binding) == 0) {
|
||||
free(current_binding);
|
||||
return;
|
||||
return (1);
|
||||
}
|
||||
|
||||
for (i = 0; i < nitems(name_to_mousefunc); i++) {
|
||||
|
@ -600,8 +601,10 @@ conf_mousebind(struct conf *c, char *name, char *binding)
|
|||
current_binding->context = name_to_mousefunc[i].context;
|
||||
current_binding->callback = name_to_mousefunc[i].handler;
|
||||
TAILQ_INSERT_TAIL(&c->mousebindingq, current_binding, entry);
|
||||
return;
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -620,33 +623,26 @@ conf_mouseunbind(struct conf *c, struct mousebinding *unbind)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Grab the mouse buttons that we need for bindings for this client
|
||||
*/
|
||||
void
|
||||
conf_grab_mouse(struct client_ctx *cc)
|
||||
conf_grab_mouse(Window win)
|
||||
{
|
||||
struct mousebinding *mb;
|
||||
int button;
|
||||
|
||||
TAILQ_FOREACH(mb, &Conf.mousebindingq, entry) {
|
||||
if (mb->context != MOUSEBIND_CTX_WIN)
|
||||
continue;
|
||||
xu_btn_grab(win, mb->modmask, mb->button);
|
||||
}
|
||||
}
|
||||
|
||||
switch(mb->button) {
|
||||
case 1:
|
||||
button = Button1;
|
||||
break;
|
||||
case 2:
|
||||
button = Button2;
|
||||
break;
|
||||
case 3:
|
||||
button = Button3;
|
||||
break;
|
||||
default:
|
||||
warnx("strange button in mousebinding\n");
|
||||
continue;
|
||||
}
|
||||
xu_btn_grab(cc->win, mb->modmask, button);
|
||||
}
|
||||
void
|
||||
conf_grab_kbd(Window win)
|
||||
{
|
||||
struct keybinding *kb;
|
||||
|
||||
XUngrabKey(X_Dpy, AnyKey, AnyModifier, win);
|
||||
|
||||
TAILQ_FOREACH(kb, &Conf.keybindingq, entry)
|
||||
xu_key_grab(win, kb->modmask, kb->keysym);
|
||||
}
|
||||
|
||||
|
|
105
font.c
105
font.c
|
@ -1,105 +0,0 @@
|
|||
/*
|
||||
* calmwm - the calm window manager
|
||||
*
|
||||
* Copyright (c) 2005 Marius Eriksen <marius@monkey.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $OpenBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include "queue.h"
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "calmwm.h"
|
||||
|
||||
int
|
||||
font_ascent(struct screen_ctx *sc)
|
||||
{
|
||||
return (sc->xftfont->ascent);
|
||||
}
|
||||
|
||||
int
|
||||
font_descent(struct screen_ctx *sc)
|
||||
{
|
||||
return (sc->xftfont->descent);
|
||||
}
|
||||
|
||||
u_int
|
||||
font_height(struct screen_ctx *sc)
|
||||
{
|
||||
return (sc->xftfont->height + 1);
|
||||
}
|
||||
|
||||
void
|
||||
font_init(struct screen_ctx *sc, const char *name, const char **color)
|
||||
{
|
||||
int i;
|
||||
XRenderColor c;
|
||||
|
||||
sc->xftdraw = XftDrawCreate(X_Dpy, sc->rootwin,
|
||||
sc->visual, sc->colormap);
|
||||
if (sc->xftdraw == NULL)
|
||||
errx(1, "XftDrawCreate");
|
||||
|
||||
sc->xftfont = XftFontOpenName(X_Dpy, sc->which, name);
|
||||
if (sc->xftfont == NULL)
|
||||
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
|
||||
font_width(struct screen_ctx *sc, const char *text, int len)
|
||||
{
|
||||
XGlyphInfo extents;
|
||||
|
||||
XftTextExtentsUtf8(X_Dpy, sc->xftfont, (const FcChar8*)text,
|
||||
len, &extents);
|
||||
|
||||
return (extents.xOff);
|
||||
}
|
||||
|
||||
void
|
||||
font_draw(struct screen_ctx *sc, const char *text, int len,
|
||||
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);
|
||||
XftDrawStringUtf8(sc->xftdraw, &sc->xftcolor[color], sc->xftfont, x, y,
|
||||
(const FcChar8*)text, len);
|
||||
}
|
11
group.c
11
group.c
|
@ -308,17 +308,6 @@ group_cycle(struct screen_ctx *sc, int flags)
|
|||
group_setactive(sc, showgroup->shortcut);
|
||||
}
|
||||
|
||||
/* called when a client is deleted */
|
||||
void
|
||||
group_client_delete(struct client_ctx *cc)
|
||||
{
|
||||
if (cc->group == NULL)
|
||||
return;
|
||||
|
||||
TAILQ_REMOVE(&cc->group->clients, cc, group_entry);
|
||||
cc->group = NULL; /* he he */
|
||||
}
|
||||
|
||||
void
|
||||
group_menu(XButtonEvent *e)
|
||||
{
|
||||
|
|
17
kbfunc.c
17
kbfunc.c
|
@ -88,17 +88,16 @@ kbfunc_moveresize(struct client_ctx *cc, union arg *arg)
|
|||
}
|
||||
switch (flags & TYPEMASK) {
|
||||
case CWM_MOVE:
|
||||
cc->geom.y += my;
|
||||
if (cc->geom.y + cc->geom.h < 0)
|
||||
cc->geom.y = -cc->geom.h;
|
||||
if (cc->geom.y > sc->view.h - 1)
|
||||
cc->geom.y = sc->view.h - 1;
|
||||
|
||||
cc->geom.x += mx;
|
||||
if (cc->geom.x + cc->geom.w < 0)
|
||||
cc->geom.x = -cc->geom.w;
|
||||
if (cc->geom.x > sc->view.w - 1)
|
||||
cc->geom.x = sc->view.w - 1;
|
||||
cc->geom.y += my;
|
||||
if (cc->geom.y + cc->geom.h < 0)
|
||||
cc->geom.y = -cc->geom.h;
|
||||
if (cc->geom.y > sc->view.h - 1)
|
||||
cc->geom.y = sc->view.h - 1;
|
||||
|
||||
cc->geom.x += client_snapcalc(cc->geom.x,
|
||||
cc->geom.x + cc->geom.w + (cc->bwidth * 2),
|
||||
|
@ -109,15 +108,15 @@ kbfunc_moveresize(struct client_ctx *cc, union arg *arg)
|
|||
|
||||
client_move(cc);
|
||||
xu_ptr_getpos(cc->win, &x, &y);
|
||||
cc->ptr.y = y + my;
|
||||
cc->ptr.x = x + mx;
|
||||
cc->ptr.y = y + my;
|
||||
client_ptrwarp(cc);
|
||||
break;
|
||||
case CWM_RESIZE:
|
||||
if ((cc->geom.h += my) < 1)
|
||||
cc->geom.h = 1;
|
||||
if ((cc->geom.w += mx) < 1)
|
||||
cc->geom.w = 1;
|
||||
if ((cc->geom.h += my) < 1)
|
||||
cc->geom.h = 1;
|
||||
client_resize(cc, 1);
|
||||
|
||||
/* Make sure the pointer stays within the window. */
|
||||
|
|
117
menu.c
117
menu.c
|
@ -65,27 +65,16 @@ struct menu_ctx {
|
|||
static struct menu *menu_handle_key(XEvent *, struct menu_ctx *,
|
||||
struct menu_q *, struct menu_q *);
|
||||
static void menu_handle_move(XEvent *, struct menu_ctx *,
|
||||
struct screen_ctx *, struct menu_q *);
|
||||
struct menu_q *);
|
||||
static struct menu *menu_handle_release(XEvent *, struct menu_ctx *,
|
||||
struct screen_ctx *, struct menu_q *);
|
||||
static void menu_draw(struct screen_ctx *, struct menu_ctx *,
|
||||
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 *,
|
||||
struct menu_q *);
|
||||
static void menu_draw(struct menu_ctx *, struct menu_q *,
|
||||
struct menu_q *);
|
||||
static void menu_draw_entry(struct menu_ctx *, struct menu_q *,
|
||||
int, int);
|
||||
static int menu_calc_entry(struct menu_ctx *, int, int);
|
||||
static struct menu *menu_complete_path(struct menu_ctx *);
|
||||
static int menu_keycode(XKeyEvent *, enum ctltype *,
|
||||
char *);
|
||||
|
||||
void
|
||||
menu_init(struct screen_ctx *sc)
|
||||
{
|
||||
sc->menuwin = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, 1, 1,
|
||||
Conf.bwidth,
|
||||
sc->xftcolor[CWM_COLOR_MENU_FG].pixel,
|
||||
sc->xftcolor[CWM_COLOR_MENU_BG].pixel);
|
||||
}
|
||||
static int menu_keycode(XKeyEvent *, enum ctltype *, char *);
|
||||
|
||||
struct menu *
|
||||
menu_filter(struct screen_ctx *sc, struct menu_q *menuq, char *prompt,
|
||||
|
@ -112,18 +101,13 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, char *prompt,
|
|||
|
||||
mc.sc = sc;
|
||||
mc.flags = flags;
|
||||
if (prompt == NULL) {
|
||||
evmask = MENUMASK;
|
||||
mc.promptstr[0] = '\0';
|
||||
mc.list = 1;
|
||||
} else {
|
||||
evmask = MENUMASK | KEYMASK; /* only accept keys if prompt */
|
||||
(void)snprintf(mc.promptstr, sizeof(mc.promptstr), "%s%s",
|
||||
prompt, PROMPT_SCHAR);
|
||||
(void)snprintf(mc.dispstr, sizeof(mc.dispstr), "%s%s%s",
|
||||
mc.promptstr, mc.searchstr, PROMPT_ECHAR);
|
||||
mc.width = font_width(sc, mc.dispstr, strlen(mc.dispstr));
|
||||
if (prompt != NULL) {
|
||||
evmask = MENUMASK | KEYMASK; /* accept keys as well */
|
||||
(void)strlcpy(mc.promptstr, prompt, sizeof(mc.promptstr));
|
||||
mc.hasprompt = 1;
|
||||
} else {
|
||||
evmask = MENUMASK;
|
||||
mc.list = 1;
|
||||
}
|
||||
|
||||
if (initial != NULL)
|
||||
|
@ -135,8 +119,6 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, char *prompt,
|
|||
mc.print = print;
|
||||
mc.entry = mc.prev = -1;
|
||||
|
||||
XMoveResizeWindow(X_Dpy, sc->menuwin, mc.x, mc.y, mc.width,
|
||||
font_height(sc));
|
||||
XSelectInput(X_Dpy, sc->menuwin, evmask);
|
||||
XMapRaised(X_Dpy, sc->menuwin);
|
||||
|
||||
|
@ -164,13 +146,13 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, char *prompt,
|
|||
goto out;
|
||||
/* FALLTHROUGH */
|
||||
case Expose:
|
||||
menu_draw(sc, &mc, menuq, &resultq);
|
||||
menu_draw(&mc, menuq, &resultq);
|
||||
break;
|
||||
case MotionNotify:
|
||||
menu_handle_move(&e, &mc, sc, &resultq);
|
||||
menu_handle_move(&e, &mc, &resultq);
|
||||
break;
|
||||
case ButtonRelease:
|
||||
if ((mi = menu_handle_release(&e, &mc, sc, &resultq))
|
||||
if ((mi = menu_handle_release(&e, &mc, &resultq))
|
||||
!= NULL)
|
||||
goto out;
|
||||
break;
|
||||
|
@ -192,6 +174,7 @@ out:
|
|||
xu_ptr_setpos(sc->rootwin, xsave, ysave);
|
||||
xu_ptr_ungrab();
|
||||
|
||||
XMoveResizeWindow(X_Dpy, sc->menuwin, 0, 0, 1, 1);
|
||||
XUnmapWindow(X_Dpy, sc->menuwin);
|
||||
XUngrabKeyboard(X_Dpy, CurrentTime);
|
||||
|
||||
|
@ -348,9 +331,9 @@ menu_handle_key(XEvent *e, struct menu_ctx *mc, struct menu_q *menuq,
|
|||
}
|
||||
|
||||
static void
|
||||
menu_draw(struct screen_ctx *sc, struct menu_ctx *mc, struct menu_q *menuq,
|
||||
struct menu_q *resultq)
|
||||
menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq)
|
||||
{
|
||||
struct screen_ctx *sc = mc->sc;
|
||||
struct menu *mi;
|
||||
struct geom xine;
|
||||
int n, xsave, ysave;
|
||||
|
@ -371,10 +354,11 @@ menu_draw(struct screen_ctx *sc, struct menu_ctx *mc, struct menu_q *menuq,
|
|||
mc->width = 0;
|
||||
mc->height = 0;
|
||||
if (mc->hasprompt) {
|
||||
(void)snprintf(mc->dispstr, sizeof(mc->dispstr), "%s%s%s",
|
||||
mc->promptstr, mc->searchstr, PROMPT_ECHAR);
|
||||
mc->width = font_width(sc, mc->dispstr, strlen(mc->dispstr));
|
||||
mc->height = font_height(sc);
|
||||
(void)snprintf(mc->dispstr, sizeof(mc->dispstr), "%s%s%s%s",
|
||||
mc->promptstr, PROMPT_SCHAR, mc->searchstr, PROMPT_ECHAR);
|
||||
mc->width = xu_xft_width(sc->xftfont, mc->dispstr,
|
||||
strlen(mc->dispstr));
|
||||
mc->height = sc->xftfont->height + 1;
|
||||
mc->num = 1;
|
||||
}
|
||||
|
||||
|
@ -389,9 +373,9 @@ menu_draw(struct screen_ctx *sc, struct menu_ctx *mc, struct menu_q *menuq,
|
|||
text = mi->text;
|
||||
}
|
||||
|
||||
mc->width = MAX(mc->width, font_width(sc, text,
|
||||
mc->width = MAX(mc->width, xu_xft_width(sc->xftfont, text,
|
||||
MIN(strlen(text), MENU_MAXENTRY)));
|
||||
mc->height += font_height(sc);
|
||||
mc->height += sc->xftfont->height + 1;
|
||||
mc->num++;
|
||||
}
|
||||
|
||||
|
@ -424,8 +408,8 @@ menu_draw(struct screen_ctx *sc, struct menu_ctx *mc, struct menu_q *menuq,
|
|||
mc->width, mc->height);
|
||||
|
||||
if (mc->hasprompt) {
|
||||
font_draw(sc, mc->dispstr, strlen(mc->dispstr), sc->menuwin, 0,
|
||||
0, font_ascent(sc));
|
||||
xu_xft_draw(sc, mc->dispstr, CWM_COLOR_MENU_FONT,
|
||||
0, sc->xftfont->ascent);
|
||||
n = 1;
|
||||
} else
|
||||
n = 0;
|
||||
|
@ -433,26 +417,26 @@ menu_draw(struct screen_ctx *sc, struct menu_ctx *mc, struct menu_q *menuq,
|
|||
TAILQ_FOREACH(mi, resultq, resultentry) {
|
||||
char *text = mi->print[0] != '\0' ?
|
||||
mi->print : mi->text;
|
||||
int y = n * font_height(sc) + font_ascent(sc) + 1;
|
||||
int y = n * (sc->xftfont->height + 1) + sc->xftfont->ascent + 1;
|
||||
|
||||
/* Stop drawing when menu doesn't fit inside the screen. */
|
||||
if (mc->y + y > xine.h)
|
||||
break;
|
||||
|
||||
font_draw(sc, text, MIN(strlen(text), MENU_MAXENTRY),
|
||||
sc->menuwin, 0, 0, y);
|
||||
xu_xft_draw(sc, text, CWM_COLOR_MENU_FONT, 0, y);
|
||||
n++;
|
||||
}
|
||||
if (mc->hasprompt && n > 1 && (mc->searchstr[0] != '\0')) {
|
||||
mc->entry = 1;
|
||||
menu_draw_entry(sc, mc, resultq, mc->entry, 1);
|
||||
menu_draw_entry(mc, resultq, mc->entry, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
menu_draw_entry(struct screen_ctx *sc, struct menu_ctx *mc,
|
||||
struct menu_q *resultq, int entry, int active)
|
||||
menu_draw_entry(struct menu_ctx *mc, struct menu_q *resultq,
|
||||
int entry, int active)
|
||||
{
|
||||
struct screen_ctx *sc = mc->sc;
|
||||
struct menu *mi;
|
||||
char *text;
|
||||
int color, i = 0;
|
||||
|
@ -469,42 +453,41 @@ menu_draw_entry(struct screen_ctx *sc, struct menu_ctx *mc,
|
|||
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);
|
||||
(sc->xftfont->height + 1) * entry, mc->width,
|
||||
(sc->xftfont->height + 1) + sc->xftfont->descent);
|
||||
color = active ? CWM_COLOR_MENU_FONT_SEL : CWM_COLOR_MENU_FONT;
|
||||
xu_xft_draw(sc, text, color,
|
||||
0, (sc->xftfont->height + 1) * entry + sc->xftfont->ascent + 1);
|
||||
}
|
||||
|
||||
static void
|
||||
menu_handle_move(XEvent *e, struct menu_ctx *mc, struct screen_ctx *sc,
|
||||
struct menu_q *resultq)
|
||||
menu_handle_move(XEvent *e, struct menu_ctx *mc, struct menu_q *resultq)
|
||||
{
|
||||
mc->prev = mc->entry;
|
||||
mc->entry = menu_calc_entry(sc, mc, e->xbutton.x, e->xbutton.y);
|
||||
mc->entry = menu_calc_entry(mc, e->xbutton.x, e->xbutton.y);
|
||||
|
||||
if (mc->prev == mc->entry)
|
||||
return;
|
||||
|
||||
if (mc->prev != -1)
|
||||
menu_draw_entry(sc, mc, resultq, mc->prev, 0);
|
||||
menu_draw_entry(mc, resultq, mc->prev, 0);
|
||||
if (mc->entry != -1) {
|
||||
(void)xu_ptr_regrab(MENUGRABMASK, Cursor_normal);
|
||||
menu_draw_entry(sc, mc, resultq, mc->entry, 1);
|
||||
menu_draw_entry(mc, resultq, mc->entry, 1);
|
||||
} else
|
||||
(void)xu_ptr_regrab(MENUGRABMASK, Cursor_default);
|
||||
|
||||
if (mc->hasprompt)
|
||||
menu_draw_entry(sc, mc, resultq, 1, 1);
|
||||
menu_draw_entry(mc, resultq, 1, 1);
|
||||
}
|
||||
|
||||
static struct menu *
|
||||
menu_handle_release(XEvent *e, struct menu_ctx *mc, struct screen_ctx *sc,
|
||||
struct menu_q *resultq)
|
||||
menu_handle_release(XEvent *e, struct menu_ctx *mc, struct menu_q *resultq)
|
||||
{
|
||||
struct menu *mi;
|
||||
int entry, i = 0;
|
||||
|
||||
entry = menu_calc_entry(sc, mc, e->xbutton.x, e->xbutton.y);
|
||||
entry = menu_calc_entry(mc, e->xbutton.x, e->xbutton.y);
|
||||
|
||||
if (mc->hasprompt)
|
||||
i = 1;
|
||||
|
@ -521,15 +504,17 @@ menu_handle_release(XEvent *e, struct menu_ctx *mc, struct screen_ctx *sc,
|
|||
}
|
||||
|
||||
static int
|
||||
menu_calc_entry(struct screen_ctx *sc, struct menu_ctx *mc, int x, int y)
|
||||
menu_calc_entry(struct menu_ctx *mc, int x, int y)
|
||||
{
|
||||
struct screen_ctx *sc = mc->sc;
|
||||
int entry;
|
||||
|
||||
entry = y / font_height(sc);
|
||||
entry = y / (sc->xftfont->height + 1);
|
||||
|
||||
/* in bounds? */
|
||||
if (x < 0 || x > mc->width || y < 0 ||
|
||||
y > font_height(sc) * mc->num || entry < 0 || entry >= mc->num)
|
||||
y > (sc->xftfont->height + 1) * mc->num ||
|
||||
entry < 0 || entry >= mc->num)
|
||||
entry = -1;
|
||||
|
||||
if (mc->hasprompt && entry == 0)
|
||||
|
|
34
mousefunc.c
34
mousefunc.c
|
@ -31,14 +31,12 @@
|
|||
|
||||
#include "calmwm.h"
|
||||
|
||||
static int mousefunc_sweep_calc(struct client_ctx *, int, int, int, int);
|
||||
static void mousefunc_sweep_calc(struct client_ctx *, int, int, int, int);
|
||||
static void mousefunc_sweep_draw(struct client_ctx *);
|
||||
|
||||
static int
|
||||
static void
|
||||
mousefunc_sweep_calc(struct client_ctx *cc, int x, int y, int mx, int my)
|
||||
{
|
||||
int width = cc->geom.w, height = cc->geom.h;
|
||||
|
||||
cc->geom.w = abs(x - mx) - cc->bwidth;
|
||||
cc->geom.h = abs(y - my) - cc->bwidth;
|
||||
|
||||
|
@ -46,32 +44,27 @@ mousefunc_sweep_calc(struct client_ctx *cc, int x, int y, int mx, int my)
|
|||
|
||||
cc->geom.x = x <= mx ? x : x - cc->geom.w;
|
||||
cc->geom.y = y <= my ? y : y - cc->geom.h;
|
||||
|
||||
return (width != cc->geom.w || height != cc->geom.h);
|
||||
}
|
||||
|
||||
static void
|
||||
mousefunc_sweep_draw(struct client_ctx *cc)
|
||||
{
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
char asize[10]; /* fits "nnnnxnnnn\0" */
|
||||
int width, width_size, width_name;
|
||||
char asize[14]; /* fits " nnnn x nnnn \0" */
|
||||
|
||||
(void)snprintf(asize, sizeof(asize), "%dx%d",
|
||||
(void)snprintf(asize, sizeof(asize), " %4d x %-4d ",
|
||||
(cc->geom.w - cc->hint.basew) / cc->hint.incw,
|
||||
(cc->geom.h - cc->hint.baseh) / cc->hint.inch);
|
||||
width_size = font_width(sc, asize, strlen(asize)) + 4;
|
||||
width_name = font_width(sc, cc->name, strlen(cc->name)) + 4;
|
||||
width = MAX(width_size, width_name);
|
||||
|
||||
XReparentWindow(X_Dpy, sc->menuwin, cc->win, 0, 0);
|
||||
XMoveResizeWindow(X_Dpy, sc->menuwin, 0, 0, width, font_height(sc) * 2);
|
||||
XMoveResizeWindow(X_Dpy, sc->menuwin, 0, 0,
|
||||
xu_xft_width(sc->xftfont, asize, strlen(asize)),
|
||||
sc->xftfont->height);
|
||||
XMapWindow(X_Dpy, sc->menuwin);
|
||||
XClearWindow(X_Dpy, sc->menuwin);
|
||||
font_draw(sc, cc->name, strlen(cc->name), sc->menuwin, 0,
|
||||
2, font_ascent(sc) + 1);
|
||||
font_draw(sc, asize, strlen(asize), sc->menuwin, 0,
|
||||
width / 2 - width_size / 2, font_height(sc) + font_ascent(sc) + 1);
|
||||
|
||||
xu_xft_draw(sc, asize, CWM_COLOR_MENU_FONT,
|
||||
0, sc->xftfont->ascent + 1);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -102,15 +95,14 @@ mousefunc_window_resize(struct client_ctx *cc, void *arg)
|
|||
client_draw_border(cc);
|
||||
break;
|
||||
case MotionNotify:
|
||||
if (mousefunc_sweep_calc(cc, x, y,
|
||||
ev.xmotion.x_root, ev.xmotion.y_root))
|
||||
/* Recompute window output */
|
||||
mousefunc_sweep_draw(cc);
|
||||
mousefunc_sweep_calc(cc, x, y,
|
||||
ev.xmotion.x_root, ev.xmotion.y_root);
|
||||
|
||||
/* don't resize more than 60 times / second */
|
||||
if ((ev.xmotion.time - ltime) > (1000 / 60)) {
|
||||
ltime = ev.xmotion.time;
|
||||
client_resize(cc, 1);
|
||||
mousefunc_sweep_draw(cc);
|
||||
}
|
||||
break;
|
||||
case ButtonRelease:
|
||||
|
|
77
parse.y
77
parse.y
|
@ -44,8 +44,7 @@ static struct file {
|
|||
char *name;
|
||||
int lineno;
|
||||
int errors;
|
||||
} *file;
|
||||
|
||||
} *file, *topfile;
|
||||
struct file *pushfile(const char *);
|
||||
int popfile(void);
|
||||
int yyparse(void);
|
||||
|
@ -119,12 +118,24 @@ main : FONTNAME STRING {
|
|||
conf->flags |= CONF_STICKY_GROUPS;
|
||||
}
|
||||
| BORDERWIDTH NUMBER {
|
||||
if ($2 < 0) {
|
||||
yyerror("invalid borderwidth: %d", $2);
|
||||
YYERROR;
|
||||
}
|
||||
conf->bwidth = $2;
|
||||
}
|
||||
| MOVEAMOUNT NUMBER {
|
||||
if ($2 < 0) {
|
||||
yyerror("invalid movemount: %d", $2);
|
||||
YYERROR;
|
||||
}
|
||||
conf->mamount = $2;
|
||||
}
|
||||
| SNAPDIST NUMBER {
|
||||
if ($2 < 0) {
|
||||
yyerror("invalid snapdist: %d", $2);
|
||||
YYERROR;
|
||||
}
|
||||
conf->snapdist = $2;
|
||||
}
|
||||
| COMMAND STRING string {
|
||||
|
@ -135,10 +146,9 @@ main : FONTNAME STRING {
|
|||
| AUTOGROUP NUMBER STRING {
|
||||
if ($2 < 0 || $2 > 9) {
|
||||
free($3);
|
||||
yyerror("autogroup number out of range: %d", $2);
|
||||
yyerror("invalid autogroup: %d", $2);
|
||||
YYERROR;
|
||||
}
|
||||
|
||||
conf_autogroup(conf, $2, $3);
|
||||
free($3);
|
||||
}
|
||||
|
@ -152,13 +162,23 @@ main : FONTNAME STRING {
|
|||
free($3);
|
||||
}
|
||||
| GAP NUMBER NUMBER NUMBER NUMBER {
|
||||
if ($2 < 0 || $3 < 0 || $4 < 0 || $5 < 0) {
|
||||
yyerror("invalid gap: %d %d %d %d",
|
||||
$2, $3, $4, $5);
|
||||
YYERROR;
|
||||
}
|
||||
conf->gap.top = $2;
|
||||
conf->gap.bottom = $3;
|
||||
conf->gap.left = $4;
|
||||
conf->gap.right = $5;
|
||||
}
|
||||
| MOUSEBIND STRING string {
|
||||
conf_mousebind(conf, $2, $3);
|
||||
if (!conf_mousebind(conf, $2, $3)) {
|
||||
yyerror("invalid mousebind: %s %s", $2, $3);
|
||||
free($2);
|
||||
free($3);
|
||||
YYERROR;
|
||||
}
|
||||
free($2);
|
||||
free($3);
|
||||
}
|
||||
|
@ -184,20 +204,20 @@ colors : ACTIVEBORDER STRING {
|
|||
conf->color[CWM_COLOR_BORDER_UNGROUP] = $2;
|
||||
}
|
||||
| MENUBG STRING {
|
||||
free(conf->menucolor[CWM_COLOR_MENU_BG]);
|
||||
conf->menucolor[CWM_COLOR_MENU_BG] = $2;
|
||||
free(conf->color[CWM_COLOR_MENU_BG]);
|
||||
conf->color[CWM_COLOR_MENU_BG] = $2;
|
||||
}
|
||||
| MENUFG STRING {
|
||||
free(conf->menucolor[CWM_COLOR_MENU_FG]);
|
||||
conf->menucolor[CWM_COLOR_MENU_FG] = $2;
|
||||
free(conf->color[CWM_COLOR_MENU_FG]);
|
||||
conf->color[CWM_COLOR_MENU_FG] = $2;
|
||||
}
|
||||
| FONTCOLOR STRING {
|
||||
free(conf->menucolor[CWM_COLOR_MENU_FONT]);
|
||||
conf->menucolor[CWM_COLOR_MENU_FONT] = $2;
|
||||
free(conf->color[CWM_COLOR_MENU_FONT]);
|
||||
conf->color[CWM_COLOR_MENU_FONT] = $2;
|
||||
}
|
||||
| FONTSELCOLOR STRING {
|
||||
free(conf->menucolor[CWM_COLOR_MENU_FONT_SEL]);
|
||||
conf->menucolor[CWM_COLOR_MENU_FONT_SEL] = $2;
|
||||
free(conf->color[CWM_COLOR_MENU_FONT_SEL]);
|
||||
conf->color[CWM_COLOR_MENU_FONT_SEL] = $2;
|
||||
}
|
||||
;
|
||||
%%
|
||||
|
@ -294,8 +314,9 @@ lgetc(int quotec)
|
|||
|
||||
if (quotec) {
|
||||
if ((c = getc(file->stream)) == EOF) {
|
||||
yyerror("reached end of file while parsing quoted string");
|
||||
if (popfile() == EOF)
|
||||
yyerror("reached end of file while parsing "
|
||||
"quoted string");
|
||||
if (file == topfile || popfile() == EOF)
|
||||
return (EOF);
|
||||
return (quotec);
|
||||
}
|
||||
|
@ -313,7 +334,7 @@ lgetc(int quotec)
|
|||
}
|
||||
|
||||
while (c == EOF) {
|
||||
if (popfile() == EOF)
|
||||
if (file == topfile || popfile() == EOF)
|
||||
return (EOF);
|
||||
c = getc(file->stream);
|
||||
}
|
||||
|
@ -342,10 +363,12 @@ findeol(void)
|
|||
int c;
|
||||
|
||||
parsebuf = NULL;
|
||||
pushback_index = 0;
|
||||
|
||||
/* skip to either EOF or the first real EOL */
|
||||
while (1) {
|
||||
if (pushback_index)
|
||||
c = pushback_buffer[--pushback_index];
|
||||
else
|
||||
c = lgetc(0);
|
||||
if (c == '\n') {
|
||||
file->lineno++;
|
||||
|
@ -447,9 +470,10 @@ nodigits:
|
|||
#define allowed_in_string(x) \
|
||||
(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
|
||||
x != '{' && x != '}' && x != '<' && x != '>' && \
|
||||
x != '!' && x != '=' && x != '#' && x != ','))
|
||||
x != '!' && x != '=' && x != '/' && x != '#' && \
|
||||
x != ','))
|
||||
|
||||
if (isalnum(c) || c == ':' || c == '_' || c == '*' || c == '/') {
|
||||
if (isalnum(c) || c == ':' || c == '_' || c == '*') {
|
||||
do {
|
||||
*p++ = c;
|
||||
if ((unsigned)(p-buf) >= sizeof(buf)) {
|
||||
|
@ -481,6 +505,7 @@ pushfile(const char *name)
|
|||
nfile->name = xstrdup(name);
|
||||
|
||||
if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
|
||||
warn("%s", nfile->name);
|
||||
free(nfile->name);
|
||||
free(nfile);
|
||||
return (NULL);
|
||||
|
@ -495,16 +520,15 @@ popfile(void)
|
|||
{
|
||||
struct file *prev;
|
||||
|
||||
if ((prev = TAILQ_PREV(file, files, entry)) != NULL) {
|
||||
if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
|
||||
prev->errors += file->errors;
|
||||
|
||||
TAILQ_REMOVE(&files, file, entry);
|
||||
fclose(file->stream);
|
||||
free(file->name);
|
||||
free(file);
|
||||
file = prev;
|
||||
return (0);
|
||||
}
|
||||
return (EOF);
|
||||
return (file ? 0 : EOF);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -518,12 +542,12 @@ parse_config(const char *filename, struct conf *xconf)
|
|||
free(conf);
|
||||
return (-1);
|
||||
}
|
||||
topfile = file;
|
||||
|
||||
conf_init(conf);
|
||||
|
||||
yyparse();
|
||||
errors = file->errors;
|
||||
file->errors = 0;
|
||||
popfile();
|
||||
|
||||
if (errors) {
|
||||
|
@ -575,12 +599,9 @@ parse_config(const char *filename, struct conf *xconf)
|
|||
(void)strlcpy(xconf->lockpath, conf->lockpath,
|
||||
sizeof(xconf->lockpath));
|
||||
|
||||
for (i = 0; i < CWM_COLOR_BORDER_MAX; i++)
|
||||
for (i = 0; i < CWM_COLOR_MAX; i++)
|
||||
xconf->color[i] = conf->color[i];
|
||||
|
||||
for (i = 0; i < CWM_COLOR_MENU_MAX; i++)
|
||||
xconf->menucolor[i] = conf->menucolor[i];
|
||||
|
||||
xconf->font = conf->font;
|
||||
}
|
||||
|
||||
|
|
7
screen.c
7
screen.c
|
@ -49,16 +49,13 @@ screen_init(int which)
|
|||
xu_ewmh_net_supported(sc);
|
||||
xu_ewmh_net_supported_wm_check(sc);
|
||||
|
||||
conf_gap(&Conf, sc);
|
||||
conf_color(&Conf, sc);
|
||||
conf_font(&Conf, sc);
|
||||
conf_screen(sc);
|
||||
|
||||
screen_update_geometry(sc);
|
||||
|
||||
TAILQ_INIT(&sc->mruq);
|
||||
|
||||
group_init(sc);
|
||||
menu_init(sc);
|
||||
|
||||
rootattr.cursor = Cursor_normal;
|
||||
rootattr.event_mask = SubstructureRedirectMask|SubstructureNotifyMask|
|
||||
|
@ -76,7 +73,7 @@ screen_init(int which)
|
|||
if (winattr.override_redirect ||
|
||||
winattr.map_state != IsViewable)
|
||||
continue;
|
||||
(void)client_new(wins[i], sc, winattr.map_state != IsUnmapped);
|
||||
(void)client_init(wins[i], sc, winattr.map_state != IsUnmapped);
|
||||
}
|
||||
XFree(wins);
|
||||
|
||||
|
|
52
xevents.c
52
xevents.c
|
@ -86,7 +86,7 @@ xev_handle_maprequest(XEvent *ee)
|
|||
|
||||
if ((cc = client_find(e->window)) == NULL) {
|
||||
XGetWindowAttributes(X_Dpy, e->window, &xattr);
|
||||
cc = client_new(e->window, screen_fromroot(xattr.root), 1);
|
||||
cc = client_init(e->window, screen_fromroot(xattr.root), 1);
|
||||
}
|
||||
|
||||
if ((cc->flags & CLIENT_IGNORE) == 0)
|
||||
|
@ -203,15 +203,14 @@ xev_handle_propertynotify(XEvent *ee)
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
TAILQ_FOREACH(sc, &Screenq, entry)
|
||||
if (sc->rootwin == e->window)
|
||||
goto test;
|
||||
return;
|
||||
test:
|
||||
TAILQ_FOREACH(sc, &Screenq, entry) {
|
||||
if (sc->rootwin == e->window) {
|
||||
if (e->atom == ewmh[_NET_DESKTOP_NAMES].atom)
|
||||
group_update_names(sc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xev_handle_enternotify(XEvent *ee)
|
||||
|
@ -277,7 +276,7 @@ xev_handle_keypress(XEvent *ee)
|
|||
struct client_ctx *cc = NULL, fakecc;
|
||||
struct keybinding *kb;
|
||||
KeySym keysym, skeysym;
|
||||
int modshift;
|
||||
u_int modshift;
|
||||
|
||||
keysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 0);
|
||||
skeysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 1);
|
||||
|
@ -322,7 +321,8 @@ xev_handle_keyrelease(XEvent *ee)
|
|||
XKeyEvent *e = &ee->xkey;
|
||||
struct screen_ctx *sc;
|
||||
struct client_ctx *cc;
|
||||
int i, keysym;
|
||||
KeySym keysym;
|
||||
u_int i;
|
||||
|
||||
sc = screen_fromroot(e->root);
|
||||
cc = client_current();
|
||||
|
@ -340,17 +340,29 @@ static void
|
|||
xev_handle_clientmessage(XEvent *ee)
|
||||
{
|
||||
XClientMessageEvent *e = &ee->xclient;
|
||||
Atom xa_wm_change_state;
|
||||
struct client_ctx *cc;
|
||||
|
||||
xa_wm_change_state = XInternAtom(X_Dpy, "WM_CHANGE_STATE", False);
|
||||
struct client_ctx *cc, *old_cc;
|
||||
|
||||
if ((cc = client_find(e->window)) == NULL)
|
||||
return;
|
||||
|
||||
if (e->message_type == xa_wm_change_state && e->format == 32 &&
|
||||
e->data.l[0] == IconicState)
|
||||
if (e->message_type == cwmh[WM_CHANGE_STATE].atom &&
|
||||
e->format == 32 && e->data.l[0] == IconicState)
|
||||
client_hide(cc);
|
||||
|
||||
if (e->message_type == ewmh[_NET_CLOSE_WINDOW].atom)
|
||||
client_send_delete(cc);
|
||||
|
||||
if (e->message_type == ewmh[_NET_ACTIVE_WINDOW].atom &&
|
||||
e->format == 32) {
|
||||
old_cc = client_current();
|
||||
if (old_cc)
|
||||
client_ptrsave(old_cc);
|
||||
client_ptrwarp(cc);
|
||||
}
|
||||
if (e->message_type == ewmh[_NET_WM_STATE].atom &&
|
||||
e->format == 32)
|
||||
xu_ewmh_handle_net_wm_state_msg(cc,
|
||||
e->data.l[0], e->data.l[1], e->data.l[2]);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -377,15 +389,13 @@ static void
|
|||
xev_handle_mappingnotify(XEvent *ee)
|
||||
{
|
||||
XMappingEvent *e = &ee->xmapping;
|
||||
struct keybinding *kb;
|
||||
|
||||
TAILQ_FOREACH(kb, &Conf.keybindingq, entry)
|
||||
conf_ungrab(&Conf, kb);
|
||||
struct screen_ctx *sc;
|
||||
|
||||
XRefreshKeyboardMapping(e);
|
||||
|
||||
TAILQ_FOREACH(kb, &Conf.keybindingq, entry)
|
||||
conf_grab(&Conf, kb);
|
||||
if (e->request == MappingKeyboard) {
|
||||
TAILQ_FOREACH(sc, &Screenq, entry)
|
||||
conf_grab_kbd(sc->rootwin);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
185
xutil.c
185
xutil.c
|
@ -33,7 +33,7 @@
|
|||
static unsigned int ign_mods[] = { 0, LockMask, Mod2Mask, Mod2Mask | LockMask };
|
||||
|
||||
int
|
||||
xu_ptr_grab(Window win, int mask, Cursor curs)
|
||||
xu_ptr_grab(Window win, u_int mask, Cursor curs)
|
||||
{
|
||||
return (XGrabPointer(X_Dpy, win, False, mask,
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
|
@ -41,7 +41,7 @@ xu_ptr_grab(Window win, int mask, Cursor curs)
|
|||
}
|
||||
|
||||
int
|
||||
xu_ptr_regrab(int mask, Cursor curs)
|
||||
xu_ptr_regrab(u_int mask, Cursor curs)
|
||||
{
|
||||
return (XChangeActivePointerGrab(X_Dpy, mask,
|
||||
curs, CurrentTime) == GrabSuccess ? 0 : -1);
|
||||
|
@ -56,7 +56,8 @@ xu_ptr_ungrab(void)
|
|||
void
|
||||
xu_btn_grab(Window win, int mask, u_int btn)
|
||||
{
|
||||
int i;
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < nitems(ign_mods); i++)
|
||||
XGrabButton(X_Dpy, btn, (mask | ign_mods[i]), win,
|
||||
False, BUTTONMASK, GrabModeAsync,
|
||||
|
@ -66,7 +67,8 @@ xu_btn_grab(Window win, int mask, u_int btn)
|
|||
void
|
||||
xu_btn_ungrab(Window win, int mask, u_int btn)
|
||||
{
|
||||
int i;
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < nitems(ign_mods); i++)
|
||||
XUngrabButton(X_Dpy, btn, (mask | ign_mods[i]), win);
|
||||
}
|
||||
|
@ -88,10 +90,10 @@ xu_ptr_setpos(Window win, int x, int y)
|
|||
}
|
||||
|
||||
void
|
||||
xu_key_grab(Window win, int mask, int keysym)
|
||||
xu_key_grab(Window win, u_int mask, KeySym keysym)
|
||||
{
|
||||
KeyCode code;
|
||||
int i;
|
||||
u_int i;
|
||||
|
||||
code = XKeysymToKeycode(X_Dpy, keysym);
|
||||
if ((XkbKeycodeToKeysym(X_Dpy, code, 0, 0) != keysym) &&
|
||||
|
@ -103,21 +105,6 @@ xu_key_grab(Window win, int mask, int keysym)
|
|||
True, GrabModeAsync, GrabModeAsync);
|
||||
}
|
||||
|
||||
void
|
||||
xu_key_ungrab(Window win, int mask, int keysym)
|
||||
{
|
||||
KeyCode code;
|
||||
int i;
|
||||
|
||||
code = XKeysymToKeycode(X_Dpy, keysym);
|
||||
if ((XkbKeycodeToKeysym(X_Dpy, code, 0, 0) != keysym) &&
|
||||
(XkbKeycodeToKeysym(X_Dpy, code, 0, 1) == keysym))
|
||||
mask |= ShiftMask;
|
||||
|
||||
for (i = 0; i < nitems(ign_mods); i++)
|
||||
XUngrabKey(X_Dpy, code, (mask | ign_mods[i]), win);
|
||||
}
|
||||
|
||||
void
|
||||
xu_configure(struct client_ctx *cc)
|
||||
{
|
||||
|
@ -138,19 +125,19 @@ xu_configure(struct client_ctx *cc)
|
|||
}
|
||||
|
||||
void
|
||||
xu_sendmsg(Window win, Atom atm, long val)
|
||||
xu_sendmsg(Window win, Atom type, Atom atm)
|
||||
{
|
||||
XEvent e;
|
||||
XClientMessageEvent e;
|
||||
|
||||
(void)memset(&e, 0, sizeof(e));
|
||||
e.xclient.type = ClientMessage;
|
||||
e.xclient.window = win;
|
||||
e.xclient.message_type = atm;
|
||||
e.xclient.format = 32;
|
||||
e.xclient.data.l[0] = val;
|
||||
e.xclient.data.l[1] = CurrentTime;
|
||||
bzero(&e, sizeof(e));
|
||||
e.type = ClientMessage;
|
||||
e.window = win;
|
||||
e.message_type = type;
|
||||
e.format = 32;
|
||||
e.data.l[0] = atm;
|
||||
e.data.l[1] = CurrentTime;
|
||||
|
||||
XSendEvent(X_Dpy, win, False, 0, &e);
|
||||
XSendEvent(X_Dpy, win, False, 0L, (XEvent *)&e);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -237,6 +224,7 @@ struct atom_ctx cwmh[CWMH_NITEMS] = {
|
|||
{"WM_PROTOCOLS", None},
|
||||
{"_MOTIF_WM_HINTS", None},
|
||||
{"UTF8_STRING", None},
|
||||
{"WM_CHANGE_STATE", None},
|
||||
};
|
||||
struct atom_ctx ewmh[EWMH_NITEMS] = {
|
||||
{"_NET_SUPPORTED", None},
|
||||
|
@ -253,12 +241,16 @@ struct atom_ctx ewmh[EWMH_NITEMS] = {
|
|||
{"_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)
|
||||
{
|
||||
int i;
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < nitems(cwmh); i++)
|
||||
cwmh[i].atom = XInternAtom(X_Dpy, cwmh[i].name, False);
|
||||
|
@ -271,7 +263,7 @@ void
|
|||
xu_ewmh_net_supported(struct screen_ctx *sc)
|
||||
{
|
||||
Atom atom[EWMH_NITEMS];
|
||||
int i;
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < nitems(ewmh); i++)
|
||||
atom[i] = ewmh[i].atom;
|
||||
|
@ -416,24 +408,125 @@ xu_ewmh_net_wm_desktop(struct client_ctx *cc)
|
|||
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&no, 1);
|
||||
}
|
||||
|
||||
unsigned long
|
||||
xu_getcolor(struct screen_ctx *sc, char *name)
|
||||
Atom *
|
||||
xu_ewmh_get_net_wm_state(struct client_ctx *cc, int *n)
|
||||
{
|
||||
XColor color, tmp;
|
||||
Atom *state, *p = NULL;
|
||||
|
||||
if (!XAllocNamedColor(X_Dpy, sc->colormap, name, &color, &tmp)) {
|
||||
warnx("XAllocNamedColor error: '%s'", name);
|
||||
return (0);
|
||||
}
|
||||
if ((*n = xu_getprop(cc->win, ewmh[_NET_WM_STATE].atom, XA_ATOM, 64L,
|
||||
(u_char **)&p)) <= 0)
|
||||
return (NULL);
|
||||
|
||||
return (color.pixel);
|
||||
state = xmalloc(*n * sizeof(Atom));
|
||||
memcpy(state, p, *n * sizeof(Atom));
|
||||
XFree((char *)p);
|
||||
|
||||
return (state);
|
||||
}
|
||||
|
||||
void
|
||||
xu_xorcolor(XRenderColor a, XRenderColor b, XRenderColor *r)
|
||||
xu_ewmh_handle_net_wm_state_msg(struct client_ctx *cc, int action,
|
||||
Atom first, Atom second)
|
||||
{
|
||||
r->red = a.red ^ b.red;
|
||||
r->green = a.green ^ b.green;
|
||||
r->blue = a.blue ^ b.blue;
|
||||
r->alpha = 0xffff;
|
||||
int i;
|
||||
static struct handlers {
|
||||
int atom;
|
||||
int property;
|
||||
void (*toggle)(struct client_ctx *);
|
||||
} handlers[] = {
|
||||
{ _NET_WM_STATE_MAXIMIZED_VERT,
|
||||
CLIENT_VMAXIMIZED,
|
||||
client_vmaximize },
|
||||
{ _NET_WM_STATE_MAXIMIZED_HORZ,
|
||||
CLIENT_HMAXIMIZED,
|
||||
client_hmaximize },
|
||||
};
|
||||
|
||||
for (i = 0; i < nitems(handlers); i++) {
|
||||
if (first != ewmh[handlers[i].atom].atom &&
|
||||
second != ewmh[handlers[i].atom].atom)
|
||||
continue;
|
||||
switch (action) {
|
||||
case _NET_WM_STATE_ADD:
|
||||
if ((cc->flags & handlers[i].property) == 0)
|
||||
handlers[i].toggle(cc);
|
||||
break;
|
||||
case _NET_WM_STATE_REMOVE:
|
||||
if (cc->flags & handlers[i].property)
|
||||
handlers[i].toggle(cc);
|
||||
break;
|
||||
case _NET_WM_STATE_TOGGLE:
|
||||
handlers[i].toggle(cc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
xu_ewmh_restore_net_wm_state(struct client_ctx *cc)
|
||||
{
|
||||
Atom *atoms;
|
||||
int i, n;
|
||||
|
||||
atoms = xu_ewmh_get_net_wm_state(cc, &n);
|
||||
for (i = 0; i < n; i++) {
|
||||
if (atoms[i] == ewmh[_NET_WM_STATE_MAXIMIZED_HORZ].atom)
|
||||
client_hmaximize(cc);
|
||||
if (atoms[i] == ewmh[_NET_WM_STATE_MAXIMIZED_VERT].atom)
|
||||
client_vmaximize(cc);
|
||||
}
|
||||
free(atoms);
|
||||
}
|
||||
|
||||
void
|
||||
xu_ewmh_set_net_wm_state(struct client_ctx *cc)
|
||||
{
|
||||
Atom *atoms, *oatoms;
|
||||
int n, i, j;
|
||||
|
||||
oatoms = xu_ewmh_get_net_wm_state(cc, &n);
|
||||
atoms = xmalloc((n + _NET_WM_STATES_NITEMS) * sizeof(Atom));
|
||||
for (i = j = 0; i < n; i++) {
|
||||
if (oatoms[i] != ewmh[_NET_WM_STATE_MAXIMIZED_HORZ].atom &&
|
||||
oatoms[i] != ewmh[_NET_WM_STATE_MAXIMIZED_VERT].atom)
|
||||
atoms[j++] = oatoms[i];
|
||||
}
|
||||
free(oatoms);
|
||||
if (cc->flags & CLIENT_HMAXIMIZED)
|
||||
atoms[j++] = ewmh[_NET_WM_STATE_MAXIMIZED_HORZ].atom;
|
||||
if (cc->flags & CLIENT_VMAXIMIZED)
|
||||
atoms[j++] = ewmh[_NET_WM_STATE_MAXIMIZED_VERT].atom;
|
||||
if (j > 0)
|
||||
XChangeProperty(X_Dpy, cc->win, ewmh[_NET_WM_STATE].atom,
|
||||
XA_ATOM, 32, PropModeReplace, (unsigned char *)atoms, j);
|
||||
else
|
||||
XDeleteProperty(X_Dpy, cc->win, ewmh[_NET_WM_STATE].atom);
|
||||
free(atoms);
|
||||
}
|
||||
|
||||
void
|
||||
xu_xorcolor(XftColor a, XftColor b, XftColor *r)
|
||||
{
|
||||
r->pixel = a.pixel ^ b.pixel;
|
||||
r->color.red = a.color.red ^ b.color.red;
|
||||
r->color.green = a.color.green ^ b.color.green;
|
||||
r->color.blue = a.color.blue ^ b.color.blue;
|
||||
r->color.alpha = 0xffff;
|
||||
}
|
||||
|
||||
int
|
||||
xu_xft_width(XftFont *xftfont, const char *text, int len)
|
||||
{
|
||||
XGlyphInfo extents;
|
||||
|
||||
XftTextExtentsUtf8(X_Dpy, xftfont, (const FcChar8*)text,
|
||||
len, &extents);
|
||||
|
||||
return (extents.xOff);
|
||||
}
|
||||
|
||||
void
|
||||
xu_xft_draw(struct screen_ctx *sc, const char *text, int color, int x, int y)
|
||||
{
|
||||
XftDrawStringUtf8(sc->xftdraw, &sc->xftcolor[color], sc->xftfont,
|
||||
x, y, (const FcChar8*)text, strlen(text));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user