mirror of
https://github.com/leahneukirchen/cwm.git
synced 2023-08-10 21:13:12 +03:00
Compare commits
35 Commits
OPENBSD_4_
...
OPENBSD_4_
Author | SHA1 | Date | |
---|---|---|---|
![]() |
590eb4f37b | ||
![]() |
f44862be9c | ||
![]() |
b13d592c57 | ||
![]() |
bcc0f73bb6 | ||
![]() |
58d12134b1 | ||
![]() |
18c7d89c98 | ||
![]() |
ee59e4a5a1 | ||
![]() |
055b244bb4 | ||
![]() |
71ad069846 | ||
![]() |
11b4b7fec6 | ||
![]() |
61f841ea58 | ||
![]() |
d7589ca80b | ||
![]() |
3eec3b3802 | ||
![]() |
d1b84c5415 | ||
![]() |
6e9fa7548b | ||
![]() |
8bbc376fd9 | ||
![]() |
2c29a1de65 | ||
![]() |
d2cfeb40b4 | ||
![]() |
382662d003 | ||
![]() |
9be7726606 | ||
![]() |
4d5dc5d9ea | ||
![]() |
5d51c8e0e5 | ||
![]() |
4c10afe2cc | ||
![]() |
eb7803269e | ||
![]() |
6df7cba24e | ||
![]() |
29cdc29c6e | ||
![]() |
3de90d44fc | ||
![]() |
fbb1edf2b3 | ||
![]() |
64f0038db7 | ||
![]() |
4f34392258 | ||
![]() |
655c33c489 | ||
![]() |
cc68490fe1 | ||
![]() |
ea96e92ac8 | ||
![]() |
8a490fc270 | ||
![]() |
8346de997f |
99
calmwm.c
99
calmwm.c
@@ -38,8 +38,12 @@ int HasXinerama, HasRandr, Randr_ev;
|
||||
int Starting;
|
||||
struct conf Conf;
|
||||
|
||||
static void _sigchld_cb(int);
|
||||
static void sigchld_cb(int);
|
||||
static void dpy_init(const char *);
|
||||
static int x_errorhandler(Display *, XErrorEvent *);
|
||||
static void x_setup(void);
|
||||
static void x_setupscreen(struct screen_ctx *, u_int);
|
||||
static void x_teardown(void);
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
@@ -63,44 +67,30 @@ main(int argc, char **argv)
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (signal(SIGCHLD, _sigchld_cb) == SIG_ERR)
|
||||
if (signal(SIGCHLD, sigchld_cb) == SIG_ERR)
|
||||
err(1, "signal");
|
||||
|
||||
group_init();
|
||||
|
||||
Starting = 1;
|
||||
dpy_init(display_name);
|
||||
|
||||
screen_init();
|
||||
group_init();
|
||||
client_init();
|
||||
|
||||
bzero(&Conf, sizeof(Conf));
|
||||
conf_setup(&Conf, conf_file);
|
||||
client_setup();
|
||||
xu_getatoms();
|
||||
x_setup();
|
||||
Starting = 0;
|
||||
|
||||
xev_init();
|
||||
|
||||
XEV_QUICK(NULL, NULL, MapRequest, xev_handle_maprequest, NULL);
|
||||
XEV_QUICK(NULL, NULL, UnmapNotify, xev_handle_unmapnotify, NULL);
|
||||
XEV_QUICK(NULL, NULL, ConfigureRequest,
|
||||
xev_handle_configurerequest, NULL);
|
||||
XEV_QUICK(NULL, NULL, PropertyNotify, xev_handle_propertynotify, NULL);
|
||||
XEV_QUICK(NULL, NULL, EnterNotify, xev_handle_enternotify, NULL);
|
||||
XEV_QUICK(NULL, NULL, LeaveNotify, xev_handle_leavenotify, NULL);
|
||||
XEV_QUICK(NULL, NULL, ButtonPress, xev_handle_buttonpress, NULL);
|
||||
XEV_QUICK(NULL, NULL, ButtonRelease, xev_handle_buttonrelease, NULL);
|
||||
XEV_QUICK(NULL, NULL, KeyPress, xev_handle_keypress, NULL);
|
||||
XEV_QUICK(NULL, NULL, KeyRelease, xev_handle_keyrelease, NULL);
|
||||
XEV_QUICK(NULL, NULL, Expose, xev_handle_expose, NULL);
|
||||
XEV_QUICK(NULL, NULL, DestroyNotify, xev_handle_destroynotify, NULL);
|
||||
XEV_QUICK(NULL, NULL, ClientMessage, xev_handle_clientmessage, NULL);
|
||||
XEV_QUICK(NULL, NULL, MappingNotify, xev_handle_mapping, NULL);
|
||||
|
||||
xev_loop();
|
||||
|
||||
x_teardown();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
dpy_init(const char *dpyname)
|
||||
{
|
||||
int i;
|
||||
@@ -112,11 +102,9 @@ dpy_init(const char *dpyname)
|
||||
XSetErrorHandler(x_errorhandler);
|
||||
|
||||
HasRandr = XRRQueryExtension(X_Dpy, &Randr_ev, &i);
|
||||
|
||||
TAILQ_INIT(&Screenq);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
x_setup(void)
|
||||
{
|
||||
struct screen_ctx *sc;
|
||||
@@ -124,7 +112,7 @@ x_setup(void)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ScreenCount(X_Dpy); i++) {
|
||||
XCALLOC(sc, struct screen_ctx);
|
||||
sc = xcalloc(1, sizeof(*sc));
|
||||
x_setupscreen(sc, i);
|
||||
TAILQ_INSERT_TAIL(&Screenq, sc, entry);
|
||||
}
|
||||
@@ -143,11 +131,20 @@ x_setup(void)
|
||||
Cursor_question = XCreateFontCursor(X_Dpy, XC_question_arrow);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
x_teardown(void)
|
||||
{
|
||||
struct screen_ctx *sc;
|
||||
|
||||
TAILQ_FOREACH(sc, &Screenq, entry)
|
||||
XFreeGC(X_Dpy, sc->gc);
|
||||
|
||||
XCloseDisplay(X_Dpy);
|
||||
}
|
||||
|
||||
static void
|
||||
x_setupscreen(struct screen_ctx *sc, u_int which)
|
||||
{
|
||||
XColor tmp;
|
||||
XGCValues gv;
|
||||
Window *wins, w0, w1;
|
||||
XWindowAttributes winattr;
|
||||
XSetWindowAttributes rootattr;
|
||||
@@ -157,41 +154,11 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
|
||||
Curscreen = sc;
|
||||
|
||||
sc->which = which;
|
||||
sc->rootwin = RootWindow(X_Dpy, which);
|
||||
|
||||
sc->rootwin = RootWindow(X_Dpy, sc->which);
|
||||
sc->xmax = DisplayWidth(X_Dpy, sc->which);
|
||||
sc->ymax = DisplayHeight(X_Dpy, sc->which);
|
||||
|
||||
XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, which),
|
||||
"black", &sc->fgcolor, &tmp);
|
||||
XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, which),
|
||||
"#00cc00", &sc->bgcolor, &tmp);
|
||||
XAllocNamedColor(X_Dpy,DefaultColormap(X_Dpy, which),
|
||||
"blue", &sc->fccolor, &tmp);
|
||||
XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, which),
|
||||
"red", &sc->redcolor, &tmp);
|
||||
XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, which),
|
||||
"#666666", &sc->graycolor, &tmp);
|
||||
XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, which),
|
||||
"white", &sc->whitecolor, &tmp);
|
||||
XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, which),
|
||||
"black", &sc->blackcolor, &tmp);
|
||||
|
||||
sc->blackpixl = BlackPixel(X_Dpy, sc->which);
|
||||
sc->whitepixl = WhitePixel(X_Dpy, sc->which);
|
||||
sc->bluepixl = sc->fccolor.pixel;
|
||||
sc->redpixl = sc->redcolor.pixel;
|
||||
sc->graypixl = sc->graycolor.pixel;
|
||||
|
||||
gv.foreground = sc->blackpixl^sc->whitepixl;
|
||||
gv.background = sc->whitepixl;
|
||||
gv.function = GXxor;
|
||||
gv.line_width = 1;
|
||||
gv.subwindow_mode = IncludeInferiors;
|
||||
|
||||
sc->gc = XCreateGC(X_Dpy, sc->rootwin,
|
||||
GCForeground|GCBackground|GCFunction|
|
||||
GCLineWidth|GCSubwindowMode, &gv);
|
||||
conf_color(&Conf);
|
||||
|
||||
font_init(sc);
|
||||
conf_font(&Conf);
|
||||
@@ -234,11 +201,9 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
|
||||
screen_init_xinerama(sc);
|
||||
|
||||
XSync(X_Dpy, False);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
x_errorhandler(Display *dpy, XErrorEvent *e)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
@@ -264,7 +229,7 @@ x_errorhandler(Display *dpy, XErrorEvent *e)
|
||||
}
|
||||
|
||||
static void
|
||||
_sigchld_cb(int which)
|
||||
sigchld_cb(int which)
|
||||
{
|
||||
pid_t pid;
|
||||
int save_errno = errno;
|
||||
|
101
calmwm.h
101
calmwm.h
@@ -33,6 +33,27 @@
|
||||
#define ChildMask (SubstructureRedirectMask|SubstructureNotifyMask)
|
||||
#define ButtonMask (ButtonPressMask|ButtonReleaseMask)
|
||||
#define MouseMask (ButtonMask|PointerMotionMask)
|
||||
#define KeyMask (KeyPressMask|ExposureMask)
|
||||
#define MenuMask (ButtonMask|ButtonMotionMask|ExposureMask| \
|
||||
PointerMotionMask)
|
||||
#define MenuGrabMask (ButtonMask|ButtonMotionMask|StructureNotifyMask|\
|
||||
PointerMotionMask)
|
||||
#define SearchMask (KeyPressMask|ExposureMask)
|
||||
|
||||
enum cwmcolor {
|
||||
CWM_COLOR_BORDOR_ACTIVE,
|
||||
CWM_COLOR_BORDER_INACTIVE,
|
||||
CWM_COLOR_BORDER_GROUP,
|
||||
CWM_COLOR_BORDER_UNGROUP,
|
||||
CWM_COLOR_FG_MENU,
|
||||
CWM_COLOR_BG_MENU,
|
||||
CWM_COLOR_MAX
|
||||
};
|
||||
|
||||
struct color {
|
||||
unsigned long pixel;
|
||||
char *name;
|
||||
};
|
||||
|
||||
struct client_ctx;
|
||||
|
||||
@@ -44,10 +65,8 @@ struct screen_ctx {
|
||||
u_int which;
|
||||
Window rootwin;
|
||||
Window menuwin;
|
||||
Colormap colormap;
|
||||
XColor bgcolor, fgcolor, fccolor, redcolor, graycolor,
|
||||
whitecolor, blackcolor;
|
||||
unsigned long blackpixl, whitepixl, redpixl, bluepixl, graypixl;
|
||||
|
||||
struct color color[CWM_COLOR_MAX];
|
||||
GC gc;
|
||||
|
||||
int altpersist;
|
||||
@@ -78,8 +97,8 @@ TAILQ_HEAD(screen_ctx_q, screen_ctx);
|
||||
#define CLIENT_DOVMAXIMIZE 0x10
|
||||
#define CLIENT_VMAXIMIZED 0x20
|
||||
|
||||
#define CLIENT_HIGHLIGHT_BLUE 1
|
||||
#define CLIENT_HIGHLIGHT_RED 2
|
||||
#define CLIENT_HIGHLIGHT_GROUP 1
|
||||
#define CLIENT_HIGHLIGHT_UNGROUP 2
|
||||
|
||||
struct winname {
|
||||
TAILQ_ENTRY(winname) entry;
|
||||
@@ -159,18 +178,6 @@ struct autogroupwin {
|
||||
|
||||
TAILQ_HEAD(autogroupwin_q, autogroupwin);
|
||||
|
||||
/* NULL/0 values indicate match any. */
|
||||
struct xevent {
|
||||
TAILQ_ENTRY(xevent) entry;
|
||||
Window *xev_win;
|
||||
Window *xev_root;
|
||||
int xev_type;
|
||||
void (*xev_cb)(struct xevent *, XEvent *);
|
||||
void *xev_arg;
|
||||
};
|
||||
|
||||
TAILQ_HEAD(xevent_q, xevent);
|
||||
|
||||
#define CWM_MOVE 0x01
|
||||
#define CWM_RESIZE 0x02
|
||||
#define CWM_PTRMOVE 0x04
|
||||
@@ -259,6 +266,14 @@ struct conf {
|
||||
#define CONF_MAMOUNT 1
|
||||
int mamount;
|
||||
|
||||
#define CONF_COLOR_ACTIVEBORDER "#CCCCCC"
|
||||
#define CONF_COLOR_INACTIVEBORDER "#666666"
|
||||
#define CONF_COLOR_GROUPBORDER "blue"
|
||||
#define CONF_COLOR_UNGROUPBORDER "red"
|
||||
#define CONF_COLOR_MENUFG "black"
|
||||
#define CONF_COLOR_MENUBG "white"
|
||||
struct color color[CWM_COLOR_MAX];
|
||||
|
||||
char termpath[MAXPATHLEN];
|
||||
char lockpath[MAXPATHLEN];
|
||||
|
||||
@@ -309,13 +324,10 @@ struct mwm_hints {
|
||||
int input_keycodetrans(KeyCode, u_int, enum ctltype *,
|
||||
char *);
|
||||
|
||||
int x_errorhandler(Display *, XErrorEvent *);
|
||||
void x_setup(void);
|
||||
void x_setupscreen(struct screen_ctx *, u_int);
|
||||
__dead void usage(void);
|
||||
|
||||
struct client_ctx *client_find(Window);
|
||||
void client_setup(void);
|
||||
void client_init(void);
|
||||
struct client_ctx *client_new(Window, struct screen_ctx *, int);
|
||||
int client_delete(struct client_ctx *);
|
||||
void client_setactive(struct client_ctx *, int);
|
||||
@@ -333,50 +345,20 @@ void client_warp(struct client_ctx *);
|
||||
void client_ptrwarp(struct client_ctx *);
|
||||
void client_ptrsave(struct client_ctx *);
|
||||
void client_draw_border(struct client_ctx *);
|
||||
void client_update(struct client_ctx *);
|
||||
void client_placecalc(struct client_ctx *);
|
||||
void client_maximize(struct client_ctx *);
|
||||
void client_vertmaximize(struct client_ctx *);
|
||||
void client_map(struct client_ctx *);
|
||||
void client_mtf(struct client_ctx *);
|
||||
struct client_ctx *client_cycle(int);
|
||||
struct client_ctx *client_mrunext(struct client_ctx *);
|
||||
struct client_ctx *client_mruprev(struct client_ctx *);
|
||||
void client_gethints(struct client_ctx *);
|
||||
void client_freehints(struct client_ctx *);
|
||||
|
||||
struct menu *menu_filter(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 xev_handle_maprequest(struct xevent *, XEvent *);
|
||||
void xev_handle_unmapnotify(struct xevent *, XEvent *);
|
||||
void xev_handle_destroynotify(struct xevent *, XEvent *);
|
||||
void xev_handle_configurerequest(struct xevent *, XEvent *);
|
||||
void xev_handle_propertynotify(struct xevent *, XEvent *);
|
||||
void xev_handle_enternotify(struct xevent *, XEvent *);
|
||||
void xev_handle_leavenotify(struct xevent *, XEvent *);
|
||||
void xev_handle_buttonpress(struct xevent *, XEvent *);
|
||||
void xev_handle_buttonrelease(struct xevent *, XEvent *);
|
||||
void xev_handle_keypress(struct xevent *, XEvent *);
|
||||
void xev_handle_keyrelease(struct xevent *, XEvent *);
|
||||
void xev_handle_expose(struct xevent *, XEvent *);
|
||||
void xev_handle_clientmessage(struct xevent *, XEvent *);
|
||||
void xev_handle_randr(struct xevent *, XEvent *);
|
||||
void xev_handle_mapping(struct xevent *, XEvent *);
|
||||
|
||||
#define XEV_QUICK(a, b, c, d, e) do { \
|
||||
xev_register(xev_new(a, b, c, d, e)); \
|
||||
} while (0)
|
||||
|
||||
/* XXX should be xu_ */
|
||||
void xev_reconfig(struct client_ctx *);
|
||||
|
||||
void xev_init(void);
|
||||
struct xevent *xev_new(Window *, Window *, int,
|
||||
void (*)(struct xevent *, XEvent *), void *);
|
||||
void xev_register(struct xevent *);
|
||||
void xev_loop(void);
|
||||
|
||||
void xu_getatoms(void);
|
||||
@@ -395,6 +377,8 @@ int xu_getprop(struct client_ctx *, Atom, Atom, long,
|
||||
char *xu_getstrprop(struct client_ctx *, Atom atm);
|
||||
void xu_setstate(struct client_ctx *, int);
|
||||
int xu_getstate(struct client_ctx *, int *);
|
||||
unsigned long xu_getcolor(struct screen_ctx *, char *);
|
||||
void xu_freecolor(struct screen_ctx *, unsigned long);
|
||||
|
||||
int u_spawn(char *);
|
||||
void u_exec(char *);
|
||||
@@ -404,9 +388,7 @@ void *xmalloc(size_t);
|
||||
void *xcalloc(size_t, size_t);
|
||||
char *xstrdup(const char *);
|
||||
|
||||
#define XMALLOC(p, t) ((p) = (t *)xmalloc(sizeof * (p)))
|
||||
#define XCALLOC(p, t) ((p) = (t *)xcalloc(1, sizeof * (p)))
|
||||
|
||||
void screen_init(void);
|
||||
struct screen_ctx *screen_fromroot(Window);
|
||||
struct screen_ctx *screen_current(void);
|
||||
void screen_updatestackingorder(void);
|
||||
@@ -418,12 +400,11 @@ void conf_client(struct client_ctx *);
|
||||
void conf_grab(struct conf *, struct keybinding *);
|
||||
void conf_ungrab(struct conf *, struct keybinding *);
|
||||
void conf_bindname(struct conf *, char *, char *);
|
||||
void conf_unbind(struct conf *, struct keybinding *);
|
||||
void conf_mousebind(struct conf *, char *, char *);
|
||||
void conf_mouseunbind(struct conf *, struct mousebinding *);
|
||||
void conf_grab_mouse(struct client_ctx *);
|
||||
void conf_reload(struct conf *);
|
||||
void conf_font(struct conf *);
|
||||
void conf_color(struct conf *);
|
||||
void conf_init(struct conf *);
|
||||
void conf_clear(struct conf *);
|
||||
void conf_cmd_add(struct conf *, char *, char *, int);
|
||||
@@ -440,12 +421,16 @@ void kbfunc_cmdexec(struct client_ctx *, union arg *);
|
||||
void kbfunc_client_label(struct client_ctx *, union arg *);
|
||||
void kbfunc_client_delete(struct client_ctx *, union arg *);
|
||||
void kbfunc_client_group(struct client_ctx *, union arg *);
|
||||
void kbfunc_client_grouponly(struct client_ctx *,
|
||||
union arg *);
|
||||
void kbfunc_client_cyclegroup(struct client_ctx *,
|
||||
union arg *);
|
||||
void kbfunc_client_nogroup(struct client_ctx *,
|
||||
union arg *);
|
||||
void kbfunc_client_grouptoggle(struct client_ctx *,
|
||||
union arg *);
|
||||
void kbfunc_client_movetogroup(struct client_ctx *,
|
||||
union arg *);
|
||||
void kbfunc_client_maximize(struct client_ctx *,
|
||||
union arg *);
|
||||
void kbfunc_client_vmaximize(struct client_ctx *,
|
||||
@@ -479,6 +464,7 @@ void search_match_exec(struct menu_q *, struct menu_q *,
|
||||
|
||||
void group_init(void);
|
||||
void group_hidetoggle(int);
|
||||
void group_only(int);
|
||||
void group_cycle(int);
|
||||
void group_sticky(struct client_ctx *);
|
||||
void group_client_delete(struct client_ctx *);
|
||||
@@ -487,6 +473,7 @@ void group_alltoggle(void);
|
||||
void group_sticky_toggle_enter(struct client_ctx *);
|
||||
void group_sticky_toggle_exit(struct client_ctx *);
|
||||
void group_autogroup(struct client_ctx *);
|
||||
void group_movetogroup(struct client_ctx *, int);
|
||||
|
||||
void font_init(struct screen_ctx *);
|
||||
int font_width(const char *, int);
|
||||
|
83
client.c
83
client.c
@@ -21,13 +21,19 @@
|
||||
#include "headers.h"
|
||||
#include "calmwm.h"
|
||||
|
||||
static int _client_inbound(struct client_ctx *, int, int);
|
||||
static struct client_ctx *client_mrunext(struct client_ctx *);
|
||||
static struct client_ctx *client_mruprev(struct client_ctx *);
|
||||
static void client_placecalc(struct client_ctx *);
|
||||
static void client_update(struct client_ctx *);
|
||||
static void client_gethints(struct client_ctx *);
|
||||
static void client_freehints(struct client_ctx *);
|
||||
static int client_inbound(struct client_ctx *, int, int);
|
||||
|
||||
static char emptystring[] = "";
|
||||
struct client_ctx *_curcc = NULL;
|
||||
|
||||
void
|
||||
client_setup(void)
|
||||
client_init(void)
|
||||
{
|
||||
TAILQ_INIT(&Clientq);
|
||||
}
|
||||
@@ -56,7 +62,7 @@ client_new(Window win, struct screen_ctx *sc, int mapped)
|
||||
if (win == None)
|
||||
return (NULL);
|
||||
|
||||
XCALLOC(cc, struct client_ctx);
|
||||
cc = xcalloc(1, sizeof(*cc));
|
||||
|
||||
XGrabServer(X_Dpy);
|
||||
|
||||
@@ -64,22 +70,8 @@ client_new(Window win, struct screen_ctx *sc, int mapped)
|
||||
cc->sc = sc;
|
||||
cc->win = win;
|
||||
cc->size = XAllocSizeHints();
|
||||
|
||||
XGetWMNormalHints(X_Dpy, cc->win, cc->size, &tmp);
|
||||
if (cc->size->width_inc == 0)
|
||||
cc->size->width_inc = 1;
|
||||
if (cc->size->height_inc == 0)
|
||||
cc->size->height_inc = 1;
|
||||
|
||||
TAILQ_INIT(&cc->nameq);
|
||||
client_setname(cc);
|
||||
|
||||
/*
|
||||
* conf_client() needs at least cc->win and cc->name
|
||||
*/
|
||||
conf_client(cc);
|
||||
|
||||
XGetWindowAttributes(X_Dpy, cc->win, &wattr);
|
||||
|
||||
if (cc->size->flags & PBaseSize) {
|
||||
cc->geom.min_dx = cc->size->base_width;
|
||||
cc->geom.min_dy = cc->size->base_height;
|
||||
@@ -88,10 +80,16 @@ client_new(Window win, struct screen_ctx *sc, int mapped)
|
||||
cc->geom.min_dy = cc->size->min_height;
|
||||
}
|
||||
|
||||
TAILQ_INIT(&cc->nameq);
|
||||
client_setname(cc);
|
||||
|
||||
conf_client(cc);
|
||||
|
||||
/* Saved pointer position */
|
||||
cc->ptr.x = -1;
|
||||
cc->ptr.y = -1;
|
||||
|
||||
XGetWindowAttributes(X_Dpy, cc->win, &wattr);
|
||||
cc->geom.x = wattr.x;
|
||||
cc->geom.y = wattr.y;
|
||||
cc->geom.width = wattr.width;
|
||||
@@ -121,11 +119,7 @@ client_new(Window win, struct screen_ctx *sc, int mapped)
|
||||
/* Notify client of its configuration. */
|
||||
xev_reconfig(cc);
|
||||
|
||||
if (state == IconicState)
|
||||
client_hide(cc);
|
||||
else
|
||||
client_unhide(cc);
|
||||
|
||||
(state == IconicState) ? client_hide(cc) : client_unhide(cc);
|
||||
xu_setstate(cc, cc->state);
|
||||
|
||||
XSync(X_Dpy, False);
|
||||
@@ -174,7 +168,6 @@ client_delete(struct client_ctx *cc)
|
||||
}
|
||||
|
||||
client_freehints(cc);
|
||||
|
||||
xfree(cc);
|
||||
|
||||
return (0);
|
||||
@@ -354,11 +347,7 @@ client_ptrwarp(struct client_ctx *cc)
|
||||
y = cc->geom.height / 2;
|
||||
}
|
||||
|
||||
if (cc->state == IconicState)
|
||||
client_unhide(cc);
|
||||
else
|
||||
client_raise(cc);
|
||||
|
||||
(cc->state == IconicState) ? client_unhide(cc) : client_raise(cc);
|
||||
xu_ptr_setpos(cc->win, x, y);
|
||||
}
|
||||
|
||||
@@ -368,7 +357,7 @@ client_ptrsave(struct client_ctx *cc)
|
||||
int x, y;
|
||||
|
||||
xu_ptr_getpos(cc->win, &x, &y);
|
||||
if (_client_inbound(cc, x, y)) {
|
||||
if (client_inbound(cc, x, y)) {
|
||||
cc->ptr.x = x;
|
||||
cc->ptr.y = y;
|
||||
}
|
||||
@@ -396,34 +385,35 @@ client_unhide(struct client_ctx *cc)
|
||||
cc->highlight = 0;
|
||||
cc->flags &= ~CLIENT_HIDDEN;
|
||||
xu_setstate(cc, NormalState);
|
||||
client_draw_border(cc);
|
||||
}
|
||||
|
||||
void
|
||||
client_draw_border(struct client_ctx *cc)
|
||||
{
|
||||
struct screen_ctx *sc = CCTOSC(cc);
|
||||
u_long pixl;
|
||||
unsigned long pixel;
|
||||
|
||||
if (cc->active)
|
||||
switch (cc->highlight) {
|
||||
case CLIENT_HIGHLIGHT_BLUE:
|
||||
pixl = sc->bluepixl;
|
||||
case CLIENT_HIGHLIGHT_GROUP:
|
||||
pixel = sc->color[CWM_COLOR_BORDER_GROUP].pixel;
|
||||
break;
|
||||
case CLIENT_HIGHLIGHT_RED:
|
||||
pixl = sc->redpixl;
|
||||
case CLIENT_HIGHLIGHT_UNGROUP:
|
||||
pixel = sc->color[CWM_COLOR_BORDER_UNGROUP].pixel;
|
||||
break;
|
||||
default:
|
||||
pixl = sc->whitepixl;
|
||||
pixel = sc->color[CWM_COLOR_BORDOR_ACTIVE].pixel;
|
||||
break;
|
||||
}
|
||||
else
|
||||
pixl = sc->graypixl;
|
||||
pixel = sc->color[CWM_COLOR_BORDER_INACTIVE].pixel;
|
||||
|
||||
XSetWindowBorderWidth(X_Dpy, cc->win, cc->bwidth);
|
||||
XSetWindowBorder(X_Dpy, cc->win, pixl);
|
||||
XSetWindowBorder(X_Dpy, cc->win, pixel);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
client_update(struct client_ctx *cc)
|
||||
{
|
||||
Atom *p;
|
||||
@@ -446,7 +436,6 @@ client_update(struct client_ctx *cc)
|
||||
void
|
||||
client_send_delete(struct client_ctx *cc)
|
||||
{
|
||||
|
||||
if (cc->xproto & CLIENT_PROTO_DELETE)
|
||||
xu_sendmsg(cc, WM_PROTOCOLS, WM_DELETE_WINDOW);
|
||||
else
|
||||
@@ -471,7 +460,7 @@ client_setname(struct client_ctx *cc)
|
||||
goto match;
|
||||
}
|
||||
|
||||
XMALLOC(wn, struct winname);
|
||||
wn = xmalloc(sizeof(*wn));
|
||||
wn->name = newname;
|
||||
TAILQ_INSERT_TAIL(&cc->nameq, wn, entry);
|
||||
cc->nameqlen++;
|
||||
@@ -539,7 +528,7 @@ client_cycle(int reverse)
|
||||
return (newcc);
|
||||
}
|
||||
|
||||
struct client_ctx *
|
||||
static struct client_ctx *
|
||||
client_mrunext(struct client_ctx *cc)
|
||||
{
|
||||
struct screen_ctx *sc = CCTOSC(cc);
|
||||
@@ -549,7 +538,7 @@ client_mrunext(struct client_ctx *cc)
|
||||
ccc : TAILQ_FIRST(&sc->mruq));
|
||||
}
|
||||
|
||||
struct client_ctx *
|
||||
static struct client_ctx *
|
||||
client_mruprev(struct client_ctx *cc)
|
||||
{
|
||||
struct screen_ctx *sc = CCTOSC(cc);
|
||||
@@ -559,7 +548,7 @@ client_mruprev(struct client_ctx *cc)
|
||||
ccc : TAILQ_LAST(&sc->mruq, cycle_entry_q));
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
client_placecalc(struct client_ctx *cc)
|
||||
{
|
||||
struct screen_ctx *sc = CCTOSC(cc);
|
||||
@@ -646,7 +635,7 @@ client_mtf(struct client_ctx *cc)
|
||||
TAILQ_INSERT_HEAD(&sc->mruq, cc, mru_entry);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
client_gethints(struct client_ctx *cc)
|
||||
{
|
||||
XClassHint xch;
|
||||
@@ -692,7 +681,7 @@ client_gethints(struct client_ctx *cc)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
client_freehints(struct client_ctx *cc)
|
||||
{
|
||||
if (cc->app_name != NULL)
|
||||
@@ -703,7 +692,7 @@ client_freehints(struct client_ctx *cc)
|
||||
}
|
||||
|
||||
static int
|
||||
_client_inbound(struct client_ctx *cc, int x, int y)
|
||||
client_inbound(struct client_ctx *cc, int x, int y)
|
||||
{
|
||||
return (x < cc->geom.width && x >= 0 &&
|
||||
y < cc->geom.height && y >= 0);
|
||||
|
99
conf.c
99
conf.c
@@ -28,6 +28,9 @@
|
||||
((tsp)->tv_sec cmp (usp)->tv_sec))
|
||||
#endif
|
||||
|
||||
static void conf_mouseunbind(struct conf *, struct mousebinding *);
|
||||
static void conf_unbind(struct conf *, struct keybinding *);
|
||||
|
||||
extern struct screen_ctx *Curscreen;
|
||||
|
||||
/* Add an command menu entry to the end of the menu */
|
||||
@@ -41,8 +44,7 @@ conf_cmd_add(struct conf *c, char *image, char *label, int flags)
|
||||
else if (strcmp(label, "lock") == 0)
|
||||
strlcpy(c->lockpath, image, sizeof(c->lockpath));
|
||||
else {
|
||||
struct cmd *cmd;
|
||||
XMALLOC(cmd, struct cmd);
|
||||
struct cmd *cmd = xmalloc(sizeof(*cmd));
|
||||
cmd->flags = flags;
|
||||
strlcpy(cmd->image, image, sizeof(cmd->image));
|
||||
strlcpy(cmd->label, label, sizeof(cmd->label));
|
||||
@@ -57,18 +59,37 @@ conf_font(struct conf *c)
|
||||
|
||||
sc = screen_current();
|
||||
|
||||
c->DefaultFont = font_make(sc, Conf.DefaultFontName);
|
||||
c->DefaultFont = font_make(sc, c->DefaultFontName);
|
||||
c->FontHeight = font_ascent() + font_descent() + 1;
|
||||
}
|
||||
|
||||
void
|
||||
conf_color(struct conf *c)
|
||||
{
|
||||
struct screen_ctx *sc;
|
||||
int i;
|
||||
|
||||
sc = screen_current();
|
||||
|
||||
for (i = 0; i < CWM_COLOR_MAX; i++) {
|
||||
xu_freecolor(sc, sc->color[i].pixel);
|
||||
sc->color[i].pixel = xu_getcolor(sc, c->color[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
conf_reload(struct conf *c)
|
||||
{
|
||||
struct client_ctx *cc;
|
||||
|
||||
if (parse_config(c->conf_path, c) == -1) {
|
||||
warnx("config file %s has errors, not reloading", c->conf_path);
|
||||
return;
|
||||
}
|
||||
|
||||
conf_color(c);
|
||||
TAILQ_FOREACH(cc, &Clientq, entry)
|
||||
client_draw_border(cc);
|
||||
conf_font(c);
|
||||
}
|
||||
|
||||
@@ -157,6 +178,19 @@ conf_init(struct conf *c)
|
||||
strlcpy(c->termpath, "xterm", sizeof(c->termpath));
|
||||
strlcpy(c->lockpath, "xlock", sizeof(c->lockpath));
|
||||
|
||||
c->color[CWM_COLOR_BORDOR_ACTIVE].name =
|
||||
xstrdup(CONF_COLOR_ACTIVEBORDER);
|
||||
c->color[CWM_COLOR_BORDER_INACTIVE].name =
|
||||
xstrdup(CONF_COLOR_INACTIVEBORDER);
|
||||
c->color[CWM_COLOR_BORDER_GROUP].name =
|
||||
xstrdup(CONF_COLOR_GROUPBORDER);
|
||||
c->color[CWM_COLOR_BORDER_UNGROUP].name =
|
||||
xstrdup(CONF_COLOR_UNGROUPBORDER);
|
||||
c->color[CWM_COLOR_FG_MENU].name =
|
||||
xstrdup(CONF_COLOR_MENUFG);
|
||||
c->color[CWM_COLOR_BG_MENU].name =
|
||||
xstrdup(CONF_COLOR_MENUBG);
|
||||
|
||||
c->DefaultFontName = xstrdup(DEFAULTFONTNAME);
|
||||
}
|
||||
|
||||
@@ -168,6 +202,7 @@ conf_clear(struct conf *c)
|
||||
struct winmatch *wm;
|
||||
struct cmd *cmd;
|
||||
struct mousebinding *mb;
|
||||
int i;
|
||||
|
||||
while ((cmd = TAILQ_FIRST(&c->cmdq)) != NULL) {
|
||||
TAILQ_REMOVE(&c->cmdq, cmd, entry);
|
||||
@@ -198,6 +233,9 @@ conf_clear(struct conf *c)
|
||||
xfree(mb);
|
||||
}
|
||||
|
||||
for (i = 0; i < CWM_COLOR_MAX; i++)
|
||||
xfree(c->color[i].name);
|
||||
|
||||
xfree(c->DefaultFontName);
|
||||
}
|
||||
|
||||
@@ -232,23 +270,18 @@ conf_client(struct client_ctx *cc)
|
||||
char *wname = cc->name;
|
||||
int ignore = 0;
|
||||
|
||||
/* Can wname be NULL? */
|
||||
if (wname != NULL) {
|
||||
TAILQ_FOREACH(wm, &Conf.ignoreq, entry) {
|
||||
if (strncasecmp(wm->title, wname, strlen(wm->title))
|
||||
== 0) {
|
||||
ignore = 1;
|
||||
break;
|
||||
}
|
||||
TAILQ_FOREACH(wm, &Conf.ignoreq, entry) {
|
||||
if (strncasecmp(wm->title, wname, strlen(wm->title)) == 0) {
|
||||
ignore = 1;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
ignore = 1;
|
||||
}
|
||||
|
||||
cc->bwidth = ignore ? 0 : Conf.bwidth;
|
||||
cc->flags |= ignore ? CLIENT_IGNORE : 0;
|
||||
}
|
||||
|
||||
struct {
|
||||
static struct {
|
||||
char *tag;
|
||||
void (*handler)(struct client_ctx *, union arg *);
|
||||
int flags;
|
||||
@@ -272,6 +305,33 @@ struct {
|
||||
{ "group7", kbfunc_client_group, 0, {.i = 7} },
|
||||
{ "group8", kbfunc_client_group, 0, {.i = 8} },
|
||||
{ "group9", kbfunc_client_group, 0, {.i = 9} },
|
||||
{ "grouponly1", kbfunc_client_grouponly, 0, {.i = 1} },
|
||||
{ "grouponly2", kbfunc_client_grouponly, 0, {.i = 2} },
|
||||
{ "grouponly3", kbfunc_client_grouponly, 0, {.i = 3} },
|
||||
{ "grouponly4", kbfunc_client_grouponly, 0, {.i = 4} },
|
||||
{ "grouponly5", kbfunc_client_grouponly, 0, {.i = 5} },
|
||||
{ "grouponly6", kbfunc_client_grouponly, 0, {.i = 6} },
|
||||
{ "grouponly7", kbfunc_client_grouponly, 0, {.i = 7} },
|
||||
{ "grouponly8", kbfunc_client_grouponly, 0, {.i = 8} },
|
||||
{ "grouponly9", kbfunc_client_grouponly, 0, {.i = 9} },
|
||||
{ "movetogroup1", kbfunc_client_movetogroup, KBFLAG_NEEDCLIENT,
|
||||
{.i = 1} },
|
||||
{ "movetogroup2", kbfunc_client_movetogroup, KBFLAG_NEEDCLIENT,
|
||||
{.i = 2} },
|
||||
{ "movetogroup3", kbfunc_client_movetogroup, KBFLAG_NEEDCLIENT,
|
||||
{.i = 3} },
|
||||
{ "movetogroup4", kbfunc_client_movetogroup, KBFLAG_NEEDCLIENT,
|
||||
{.i = 4} },
|
||||
{ "movetogroup5", kbfunc_client_movetogroup, KBFLAG_NEEDCLIENT,
|
||||
{.i = 5} },
|
||||
{ "movetogroup6", kbfunc_client_movetogroup, KBFLAG_NEEDCLIENT,
|
||||
{.i = 6} },
|
||||
{ "movetogroup7", kbfunc_client_movetogroup, KBFLAG_NEEDCLIENT,
|
||||
{.i = 7} },
|
||||
{ "movetogroup8", kbfunc_client_movetogroup, KBFLAG_NEEDCLIENT,
|
||||
{.i = 8} },
|
||||
{ "movetogroup9", kbfunc_client_movetogroup, KBFLAG_NEEDCLIENT,
|
||||
{.i = 9} },
|
||||
{ "nogroup", kbfunc_client_nogroup, 0, {0} },
|
||||
{ "cyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_CYCLEGROUP} },
|
||||
{ "rcyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_RCYCLEGROUP} },
|
||||
@@ -349,7 +409,6 @@ conf_grab(struct conf *c, struct keybinding *kb)
|
||||
|
||||
TAILQ_FOREACH(sc, &Screenq, entry)
|
||||
xu_key_grab(sc->rootwin, kb->modmask, kb->keysym);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -372,7 +431,7 @@ conf_bindname(struct conf *c, char *name, char *binding)
|
||||
char *substring;
|
||||
int iter;
|
||||
|
||||
XCALLOC(current_binding, struct keybinding);
|
||||
current_binding = xcalloc(1, sizeof(*current_binding));
|
||||
|
||||
if (strchr(name, 'C') != NULL &&
|
||||
strchr(name, 'C') < strchr(name, '-'))
|
||||
@@ -437,7 +496,7 @@ conf_bindname(struct conf *c, char *name, char *binding)
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
conf_unbind(struct conf *c, struct keybinding *unbind)
|
||||
{
|
||||
struct keybinding *key = NULL, *keynxt;
|
||||
@@ -459,7 +518,7 @@ conf_unbind(struct conf *c, struct keybinding *unbind)
|
||||
}
|
||||
}
|
||||
|
||||
struct {
|
||||
static struct {
|
||||
char *tag;
|
||||
void (*handler)(struct client_ctx *, void *);
|
||||
int context;
|
||||
@@ -484,7 +543,7 @@ conf_mousebind(struct conf *c, char *name, char *binding)
|
||||
const char *errstr;
|
||||
int iter;
|
||||
|
||||
XCALLOC(current_binding, struct mousebinding);
|
||||
current_binding = xcalloc(1, sizeof(*current_binding));
|
||||
|
||||
if (strchr(name, 'C') != NULL &&
|
||||
strchr(name, 'C') < strchr(name, '-'))
|
||||
@@ -527,7 +586,7 @@ conf_mousebind(struct conf *c, char *name, char *binding)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
conf_mouseunbind(struct conf *c, struct mousebinding *unbind)
|
||||
{
|
||||
struct mousebinding *mb = NULL, *mbnxt;
|
||||
|
104
cwm.1
104
cwm.1
@@ -14,7 +14,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: September 22 2008 $
|
||||
.Dd $Mdocdate: June 18 2009 $
|
||||
.Dt CWM 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -36,29 +36,29 @@ The following notation is used throughout this page:
|
||||
.Pp
|
||||
.Bl -tag -width Ds -offset indent -compact
|
||||
.It Ic C
|
||||
Control
|
||||
Control.
|
||||
.It Ic M
|
||||
Meta
|
||||
Meta.
|
||||
.It Ic S
|
||||
Shift
|
||||
Shift.
|
||||
.It Ic M1
|
||||
Left mouse button
|
||||
Left mouse button.
|
||||
.It Ic M2
|
||||
Middle mouse button
|
||||
Middle mouse button.
|
||||
.It Ic M3
|
||||
Right mouse button
|
||||
Right mouse button.
|
||||
.El
|
||||
.Pp
|
||||
.Nm
|
||||
is very simple in its use.
|
||||
Most of the actions are initiated via keybindings.
|
||||
The current keybindings are described below;
|
||||
Most of the actions are initiated via key bindings.
|
||||
The current key bindings are described below;
|
||||
their functionality is described in more detail later.
|
||||
.Pp
|
||||
.Bl -tag -width "C-M-EscapeXXX" -offset indent -compact
|
||||
.It Ic C-M-Return
|
||||
.Bl -tag -width "CM-EscapeXXXXX" -offset indent -compact
|
||||
.It Ic CM-Return
|
||||
Spawn a new terminal.
|
||||
.It Ic C-M-Delete
|
||||
.It Ic CM-Delete
|
||||
Lock the screen.
|
||||
.It Ic M-Return
|
||||
Hide current window.
|
||||
@@ -70,50 +70,50 @@ Raise current window.
|
||||
Search for windows.
|
||||
.It Ic C-/
|
||||
Search for applications.
|
||||
.It Ic C-M-n
|
||||
.It Ic CM-n
|
||||
Label current window.
|
||||
.It Ic M-Tab
|
||||
Cycle through currently visible windows.
|
||||
.It Ic M-S-Tab
|
||||
.It Ic MS-Tab
|
||||
Reverse cycle through currently visible windows.
|
||||
.It Ic C-M-x
|
||||
.It Ic CM-x
|
||||
Delete current window.
|
||||
.It Ic C-M-[n]
|
||||
.It Ic CM-[n]
|
||||
Select group n, where n is 1-9.
|
||||
.It Ic C-M-0
|
||||
.It Ic CM-0
|
||||
Select all groups.
|
||||
.It Ic C-M-g
|
||||
.It Ic CM-g
|
||||
Toggle group membership of current window.
|
||||
.It Ic M-Right
|
||||
Cycle through active groups.
|
||||
.It Ic M-Left
|
||||
Reverse cycle through active groups.
|
||||
.It Ic C-M-f
|
||||
.It Ic CM-f
|
||||
Toggle full-screen size of current window.
|
||||
.It Ic C-M-=
|
||||
.It Ic CM-=
|
||||
Toggle vertical maximization of current window.
|
||||
.It Ic M-?
|
||||
Spawn
|
||||
.Dq Exec program
|
||||
.Dq exec program
|
||||
dialog.
|
||||
.It Ic M-.
|
||||
Spawn
|
||||
.Dq Ssh to
|
||||
.Dq ssh to
|
||||
dialog.
|
||||
This parses
|
||||
.Pa $HOME/.ssh/known_hosts
|
||||
to provide host auto-completion.
|
||||
.Xr ssh 1
|
||||
will be executed via the configured terminal emulator.
|
||||
.It Ic C-M-w
|
||||
.It Ic CM-w
|
||||
Spawn
|
||||
.Dq Exec WindowManager
|
||||
.Dq exec WindowManager
|
||||
dialog; allows you to switch from
|
||||
.Nm
|
||||
to another window manager without restarting the X server.
|
||||
.It Ic C-M-S-r
|
||||
.It Ic CMS-r
|
||||
Reload configuration.
|
||||
.It Ic C-M-S-q
|
||||
.It Ic CMS-q
|
||||
Quit
|
||||
.Nm .
|
||||
.El
|
||||
@@ -121,15 +121,15 @@ Quit
|
||||
The mouse bindings are also important, they are:
|
||||
.Pp
|
||||
.Bl -tag -width Ds -offset indent -compact
|
||||
.It M-M1
|
||||
.It Ic M-M1
|
||||
Move current window.
|
||||
.It C-M-M1
|
||||
.It Ic CM-M1
|
||||
Toggle group membership of current window.
|
||||
.It M-M2
|
||||
.It Ic M-M2
|
||||
Resize current window
|
||||
.It M-M3
|
||||
.It Ic M-M3
|
||||
Lower current window.
|
||||
.It CMS-M3
|
||||
.It Ic CMS-M3
|
||||
Hide current window.
|
||||
.El
|
||||
.Pp
|
||||
@@ -145,22 +145,34 @@ Specify the display to use.
|
||||
.El
|
||||
.Sh POINTER MOVEMENT
|
||||
The pointer can be moved with the use of the keyboard through bindings.
|
||||
C-[UP|DOWN|LEFT|RIGHT] moves the pointer a small amount, while
|
||||
C-shift-[UP|DOWN|LEFT|RIGHT] moves the pointer a larger amount.
|
||||
.Ic C-[Up|Down|Left|Right]
|
||||
moves the pointer a small amount, while
|
||||
.Ic CS-[Up|Down|Left|Right]
|
||||
moves the pointer a larger amount.
|
||||
For example, to move the pointer to the left by a small amount,
|
||||
press C-LEFT.
|
||||
To move the pointer down by a larger amount, press C-shift-DOWN.
|
||||
press
|
||||
.Ic C-Left .
|
||||
To move the pointer down by a larger amount, press
|
||||
.Ic CS-Down .
|
||||
.Sh WINDOW MOVEMENT AND RESIZING
|
||||
.Nm
|
||||
windows can be moved with the use of the keyboard through Vi-like bindings.
|
||||
M-[hjkl] moves the current window a small amount, while M-shift-[hjkl] moves
|
||||
the current window a larger amount.
|
||||
For example, to move the current window to the left a small amount, press M-h.
|
||||
To move the current window down by a larger amount, press M-shift-j.
|
||||
windows can be moved with the use of the keyboard through
|
||||
.Cm vi Ns -like
|
||||
bindings.
|
||||
.Ic M-[hjkl]
|
||||
moves the current window a small amount, while
|
||||
.Ic MS-[hjkl]
|
||||
moves the current window a larger amount.
|
||||
For example, to move the current window to the left a small amount, press
|
||||
.Ic M-h .
|
||||
To move the current window down by a larger amount, press
|
||||
.Ic MS-j .
|
||||
.Pp
|
||||
Similarly, windows may be resized with the same keybindings with the addition
|
||||
Similarly, windows may be resized with the same key bindings with the addition
|
||||
of the Control key.
|
||||
C-M-[hjkl] resizes the window a small amount and C-M-shift-[hjkl]
|
||||
.Ic CM-[hjkl]
|
||||
resizes the window a small amount and
|
||||
.Ic CMS-[hjkl]
|
||||
resizes by a larger increment.
|
||||
.Sh SEARCH
|
||||
.Nm
|
||||
@@ -181,7 +193,7 @@ The window is the currently focused window.
|
||||
The window is hidden.
|
||||
.El
|
||||
.Pp
|
||||
The following keybindings may be used to navigate the result list:
|
||||
The following key bindings may be used to navigate the result list:
|
||||
.Pp
|
||||
.Bl -tag -width "[Down] or C-s or M-j" -offset indent -compact
|
||||
.It Ic [Down], C-s No or Ic M-j
|
||||
@@ -217,13 +229,13 @@ and a red border will be shown on those just removed.
|
||||
Menus are recalled by clicking the mouse on the root window:
|
||||
.Pp
|
||||
.Bl -tag -width 10n -offset -indent -compact
|
||||
.It M1
|
||||
.It Ic M1
|
||||
Show list of currently hidden windows.
|
||||
Clicking on an item will unhide that window.
|
||||
.It M2
|
||||
.It Ic M2
|
||||
Show list of currently defined groups.
|
||||
Clicking on an item will hide/unhide that group.
|
||||
.It M3
|
||||
.It Ic M3
|
||||
Show list of applications as defined in
|
||||
.Pa ~/.cwmrc .
|
||||
Clicking on an item will spawn that application.
|
||||
|
32
cwmrc.5
32
cwmrc.5
@@ -14,7 +14,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: February 7 2009 $
|
||||
.Dd $Mdocdate: May 17 2009 $
|
||||
.Dt CWMRC 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -84,6 +84,18 @@ application.
|
||||
Set the window border width to
|
||||
.Ar pixels .
|
||||
.Pp
|
||||
.It Ic color activeborder Ar color
|
||||
Set the color of the active border.
|
||||
.Pp
|
||||
.It Ic color groupborder Ar color
|
||||
Set the color of the border while grouping a window.
|
||||
.Pp
|
||||
.It Ic color inactiveborder Ar color
|
||||
Set the color of the inactive border.
|
||||
.Pp
|
||||
.It Ic color ungroupborder Ar color
|
||||
Set the color of the border while ungrouping a window.
|
||||
.Pp
|
||||
.It Ic command Ar name Ar path
|
||||
Every
|
||||
.Ar name
|
||||
@@ -158,9 +170,9 @@ should be followed by number:
|
||||
.It 1
|
||||
Left mouse button.
|
||||
.It 2
|
||||
Right mouse button.
|
||||
.It 3
|
||||
Middle mouse button.
|
||||
.It 3
|
||||
Right mouse button.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
@@ -208,6 +220,12 @@ ignore xclock
|
||||
bind CM-r label
|
||||
bind CS-Return "xterm -e top"
|
||||
bind 4-o unmap
|
||||
bind M-1 grouponly1
|
||||
bind M-2 grouponly2
|
||||
bind M-3 grouponly3
|
||||
bind MS-1 movetogroup1
|
||||
bind MS-2 movetogroup2
|
||||
bind MS-3 movetogroup3
|
||||
|
||||
# Mousebindings
|
||||
mousebind M-2 window_lower
|
||||
@@ -242,10 +260,16 @@ Launch
|
||||
menu.
|
||||
.It group[n]
|
||||
Select group n, where n is 1-9.
|
||||
.It grouponly[n]
|
||||
Like
|
||||
.Ar group[n]
|
||||
but also hides the other groups.
|
||||
.It nogroup
|
||||
Select all groups.
|
||||
.It grouptoggle
|
||||
Toggle group membership of current window.
|
||||
.It movetogroup[n]
|
||||
Hide current window from display and move to group n, where n is 1-9.
|
||||
.It cyclegroup
|
||||
Forward cycle through groups.
|
||||
.It rcyclegroup
|
||||
@@ -380,7 +404,7 @@ Toggle group membership of current window.
|
||||
.It menu_group
|
||||
Launch group list.
|
||||
.It menu_unhide
|
||||
Launch group list.
|
||||
Launch hidden window list.
|
||||
.It menu_cmd
|
||||
Launch command list.
|
||||
.El
|
||||
|
14
font.c
14
font.c
@@ -22,22 +22,14 @@
|
||||
void
|
||||
font_init(struct screen_ctx *sc)
|
||||
{
|
||||
XColor xcolor, tmp;
|
||||
|
||||
sc->xftdraw = XftDrawCreate(X_Dpy, sc->rootwin,
|
||||
DefaultVisual(X_Dpy, sc->which), DefaultColormap(X_Dpy, sc->which));
|
||||
if (sc->xftdraw == NULL)
|
||||
errx(1, "XftDrawCreate");
|
||||
|
||||
if (!XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, sc->which),
|
||||
"black", &xcolor, &tmp))
|
||||
errx(1, "XAllocNamedColor");
|
||||
|
||||
sc->xftcolor.color.red = xcolor.red;
|
||||
sc->xftcolor.color.green = xcolor.green;
|
||||
sc->xftcolor.color.blue = xcolor.blue;
|
||||
sc->xftcolor.color.alpha = 0x00ff00;
|
||||
sc->xftcolor.pixel = xcolor.pixel;
|
||||
if (!XftColorAllocName(X_Dpy, DefaultVisual(X_Dpy, sc->which),
|
||||
DefaultColormap(X_Dpy, sc->which), "black", &sc->xftcolor))
|
||||
errx(1, "XftColorAllocName");
|
||||
}
|
||||
|
||||
int
|
||||
|
91
group.c
91
group.c
@@ -24,11 +24,11 @@
|
||||
|
||||
#define CALMWM_NGROUPS 9
|
||||
|
||||
static void _group_add(struct group_ctx *, struct client_ctx *);
|
||||
static void _group_remove(struct client_ctx *);
|
||||
static void _group_hide(struct group_ctx *);
|
||||
static void _group_show(struct group_ctx *);
|
||||
static void _group_fix_hidden_state(struct group_ctx *);
|
||||
static void group_add(struct group_ctx *, struct client_ctx *);
|
||||
static void group_remove(struct client_ctx *);
|
||||
static void group_hide(struct group_ctx *);
|
||||
static void group_show(struct group_ctx *);
|
||||
static void group_fix_hidden_state(struct group_ctx *);
|
||||
|
||||
struct group_ctx *Group_active = NULL;
|
||||
struct group_ctx Groups[CALMWM_NGROUPS];
|
||||
@@ -41,10 +41,10 @@ const char *shortcut_to_name[] = {
|
||||
};
|
||||
|
||||
static void
|
||||
_group_add(struct group_ctx *gc, struct client_ctx *cc)
|
||||
group_add(struct group_ctx *gc, struct client_ctx *cc)
|
||||
{
|
||||
if (cc == NULL || gc == NULL)
|
||||
errx(1, "_group_add: a ctx is NULL");
|
||||
errx(1, "group_add: a ctx is NULL");
|
||||
|
||||
if (cc->group == gc)
|
||||
return;
|
||||
@@ -60,10 +60,10 @@ _group_add(struct group_ctx *gc, struct client_ctx *cc)
|
||||
}
|
||||
|
||||
static void
|
||||
_group_remove(struct client_ctx *cc)
|
||||
group_remove(struct client_ctx *cc)
|
||||
{
|
||||
if (cc == NULL || cc->group == NULL)
|
||||
errx(1, "_group_remove: a ctx is NULL");
|
||||
errx(1, "group_remove: a ctx is NULL");
|
||||
|
||||
XChangeProperty(X_Dpy, cc->win, _CWM_GRP, XA_STRING, 8,
|
||||
PropModeReplace, shortcut_to_name[0],
|
||||
@@ -74,7 +74,7 @@ _group_remove(struct client_ctx *cc)
|
||||
}
|
||||
|
||||
static void
|
||||
_group_hide(struct group_ctx *gc)
|
||||
group_hide(struct group_ctx *gc)
|
||||
{
|
||||
struct client_ctx *cc;
|
||||
|
||||
@@ -92,7 +92,7 @@ _group_hide(struct group_ctx *gc)
|
||||
}
|
||||
|
||||
static void
|
||||
_group_show(struct group_ctx *gc)
|
||||
group_show(struct group_ctx *gc)
|
||||
{
|
||||
struct client_ctx *cc;
|
||||
Window *winlist;
|
||||
@@ -146,6 +146,17 @@ group_init(void)
|
||||
Group_active = &Groups[0];
|
||||
}
|
||||
|
||||
void
|
||||
group_movetogroup(struct client_ctx *cc, int idx)
|
||||
{
|
||||
if (idx < 0 || idx >= CALMWM_NGROUPS)
|
||||
err(1, "group_movetogroup: index out of range (%d)", idx);
|
||||
|
||||
if(Group_active != &Groups[idx])
|
||||
client_hide(cc);
|
||||
group_add(&Groups[idx], cc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Colouring for groups upon add/remove.
|
||||
*/
|
||||
@@ -157,11 +168,11 @@ group_sticky_toggle_enter(struct client_ctx *cc)
|
||||
gc = Group_active;
|
||||
|
||||
if (gc == cc->group) {
|
||||
_group_remove(cc);
|
||||
cc->highlight = CLIENT_HIGHLIGHT_RED;
|
||||
group_remove(cc);
|
||||
cc->highlight = CLIENT_HIGHLIGHT_UNGROUP;
|
||||
} else {
|
||||
_group_add(gc, cc);
|
||||
cc->highlight = CLIENT_HIGHLIGHT_BLUE;
|
||||
group_add(gc, cc);
|
||||
cc->highlight = CLIENT_HIGHLIGHT_GROUP;
|
||||
}
|
||||
|
||||
client_draw_border(cc);
|
||||
@@ -178,7 +189,7 @@ group_sticky_toggle_exit(struct client_ctx *cc)
|
||||
* if group_hidetoggle would produce no effect, toggle the group's hidden state
|
||||
*/
|
||||
static void
|
||||
_group_fix_hidden_state(struct group_ctx *gc)
|
||||
group_fix_hidden_state(struct group_ctx *gc)
|
||||
{
|
||||
struct client_ctx *cc;
|
||||
int same = 0;
|
||||
@@ -202,17 +213,33 @@ group_hidetoggle(int idx)
|
||||
|
||||
gc = &Groups[idx];
|
||||
|
||||
_group_fix_hidden_state(gc);
|
||||
group_fix_hidden_state(gc);
|
||||
|
||||
if (gc->hidden)
|
||||
_group_show(gc);
|
||||
group_show(gc);
|
||||
else {
|
||||
_group_hide(gc);
|
||||
group_hide(gc);
|
||||
if (TAILQ_EMPTY(&gc->clients))
|
||||
Group_active = gc;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
group_only(int idx)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (idx < 0 || idx >= CALMWM_NGROUPS)
|
||||
err(1, "group_only: index out of range (%d)", idx);
|
||||
|
||||
for (i = 0; i < CALMWM_NGROUPS; i++) {
|
||||
if (i == idx)
|
||||
group_show(&Groups[i]);
|
||||
else
|
||||
group_hide(&Groups[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Cycle through active groups. If none exist, then just stay put.
|
||||
*/
|
||||
@@ -236,16 +263,16 @@ group_cycle(int reverse)
|
||||
if (!TAILQ_EMPTY(&gc->clients) && showgroup == NULL)
|
||||
showgroup = gc;
|
||||
else if (!gc->hidden)
|
||||
_group_hide(gc);
|
||||
group_hide(gc);
|
||||
}
|
||||
|
||||
if (showgroup == NULL)
|
||||
return;
|
||||
|
||||
_group_hide(Group_active);
|
||||
group_hide(Group_active);
|
||||
|
||||
if (showgroup->hidden)
|
||||
_group_show(showgroup);
|
||||
group_show(showgroup);
|
||||
else
|
||||
Group_active = showgroup;
|
||||
}
|
||||
@@ -277,7 +304,7 @@ group_menu(XButtonEvent *e)
|
||||
if (TAILQ_EMPTY(&gc->clients))
|
||||
continue;
|
||||
|
||||
XCALLOC(mi, struct menu);
|
||||
mi = xcalloc(1, sizeof(*mi));
|
||||
if (gc->hidden)
|
||||
snprintf(mi->text, sizeof(mi->text), "%d: [%s]",
|
||||
gc->shortcut, shortcut_to_name[gc->shortcut]);
|
||||
@@ -298,10 +325,7 @@ group_menu(XButtonEvent *e)
|
||||
|
||||
gc = (struct group_ctx *)mi->ctx;
|
||||
|
||||
if (gc->hidden)
|
||||
_group_show(gc);
|
||||
else
|
||||
_group_hide(gc);
|
||||
(gc->hidden) ? group_show(gc) : group_hide(gc);
|
||||
|
||||
cleanup:
|
||||
while ((mi = TAILQ_FIRST(&menuq)) != NULL) {
|
||||
@@ -317,15 +341,12 @@ group_alltoggle(void)
|
||||
|
||||
for (i = 0; i < CALMWM_NGROUPS; i++) {
|
||||
if (Grouphideall)
|
||||
_group_show(&Groups[i]);
|
||||
group_show(&Groups[i]);
|
||||
else
|
||||
_group_hide(&Groups[i]);
|
||||
group_hide(&Groups[i]);
|
||||
}
|
||||
|
||||
if (Grouphideall)
|
||||
Grouphideall = 0;
|
||||
else
|
||||
Grouphideall = 1;
|
||||
Grouphideall = (Grouphideall) ? 0 : 1;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -358,12 +379,12 @@ group_autogroup(struct client_ctx *cc)
|
||||
|
||||
TAILQ_FOREACH(gc, &Groupq, entry) {
|
||||
if (strcmp(shortcut_to_name[gc->shortcut], group) == 0) {
|
||||
_group_add(gc, cc);
|
||||
group_add(gc, cc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Conf.flags & CONF_STICKY_GROUPS)
|
||||
_group_add(Group_active, cc);
|
||||
group_add(Group_active, cc);
|
||||
|
||||
}
|
||||
|
33
headers.h
33
headers.h
@@ -21,36 +21,33 @@
|
||||
#ifndef _CALMWM_HEADERS_H_
|
||||
#define _CALMWM_HEADERS_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <sys/queue.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <getopt.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xft/Xft.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xos.h>
|
||||
#include <X11/Xproto.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/cursorfont.h>
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xproto.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
#include <X11/Xos.h>
|
||||
#include <X11/Xft/Xft.h>
|
||||
|
||||
#include <err.h>
|
||||
|
||||
#endif /* _CALMWM_HEADERS_H_ */
|
||||
|
5
input.c
5
input.c
@@ -29,10 +29,7 @@ input_keycodetrans(KeyCode kc, u_int state, enum ctltype *ctl, char *chr)
|
||||
*ctl = CTL_NONE;
|
||||
*chr = '\0';
|
||||
|
||||
if (state & ShiftMask)
|
||||
ks = XKeycodeToKeysym(X_Dpy, kc, 1);
|
||||
else
|
||||
ks = XKeycodeToKeysym(X_Dpy, kc, 0);
|
||||
ks = XKeycodeToKeysym(X_Dpy, kc, (state & ShiftMask) ? 1 : 0);
|
||||
|
||||
/* Look for control characters. */
|
||||
switch (ks) {
|
||||
|
25
kbfunc.c
25
kbfunc.c
@@ -135,7 +135,7 @@ kbfunc_client_search(struct client_ctx *scratch, union arg *arg)
|
||||
TAILQ_INIT(&menuq);
|
||||
|
||||
TAILQ_FOREACH(cc, &Clientq, entry) {
|
||||
XCALLOC(mi, struct menu);
|
||||
mi = xcalloc(1, sizeof(*mi));
|
||||
strlcpy(mi->text, cc->name, sizeof(mi->text));
|
||||
mi->ctx = cc;
|
||||
TAILQ_INSERT_TAIL(&menuq, mi, entry);
|
||||
@@ -168,7 +168,7 @@ kbfunc_menu_search(struct client_ctx *scratch, union arg *arg)
|
||||
TAILQ_INIT(&menuq);
|
||||
|
||||
TAILQ_FOREACH(cmd, &Conf.cmdq, entry) {
|
||||
XCALLOC(mi, struct menu);
|
||||
mi = xcalloc(1, sizeof(*mi));
|
||||
strlcpy(mi->text, cmd->label, sizeof(mi->text));
|
||||
mi->ctx = cmd;
|
||||
TAILQ_INSERT_TAIL(&menuq, mi, entry);
|
||||
@@ -304,7 +304,7 @@ kbfunc_exec(struct client_ctx *scratch, union arg *arg)
|
||||
continue;
|
||||
executable:
|
||||
/* the thing in tpath, we may execute */
|
||||
XCALLOC(mi, struct menu);
|
||||
mi = xcalloc(1, sizeof(*mi));
|
||||
strlcpy(mi->text, dp->d_name, sizeof(mi->text));
|
||||
TAILQ_INSERT_TAIL(&menuq, mi, entry);
|
||||
}
|
||||
@@ -380,7 +380,7 @@ kbfunc_ssh(struct client_ctx *scratch, union arg *arg)
|
||||
if (p - buf + 1 > sizeof(hostbuf))
|
||||
continue;
|
||||
(void) strlcpy(hostbuf, buf, p - buf + 1);
|
||||
XCALLOC(mi, struct menu);
|
||||
mi = xcalloc(1, sizeof(*mi));
|
||||
(void) strlcpy(mi->text, hostbuf, sizeof(mi->text));
|
||||
TAILQ_INSERT_TAIL(&menuq, mi, entry);
|
||||
}
|
||||
@@ -412,10 +412,7 @@ kbfunc_client_label(struct client_ctx *cc, union arg *arg)
|
||||
|
||||
TAILQ_INIT(&menuq);
|
||||
|
||||
if (cc->label != NULL)
|
||||
current = cc->label;
|
||||
else
|
||||
current = NULL;
|
||||
current = cc->label;
|
||||
|
||||
if ((mi = menu_filter(&menuq, "label", current, 1,
|
||||
search_match_text, NULL)) != NULL) {
|
||||
@@ -438,6 +435,12 @@ kbfunc_client_group(struct client_ctx *cc, union arg *arg)
|
||||
group_hidetoggle(KBTOGROUP(arg->i));
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_client_grouponly(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
group_only(KBTOGROUP(arg->i));
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_client_cyclegroup(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
@@ -460,6 +463,12 @@ kbfunc_client_grouptoggle(struct client_ctx *cc, union arg *arg)
|
||||
group_sticky_toggle_enter(cc);
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_client_movetogroup(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
group_movetogroup(cc, KBTOGROUP(arg->i));
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_client_maximize(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
|
40
menu.c
40
menu.c
@@ -18,11 +18,6 @@
|
||||
#include "headers.h"
|
||||
#include "calmwm.h"
|
||||
|
||||
#define KeyMask (KeyPressMask|ExposureMask)
|
||||
#define MenuMask (ButtonMask|ButtonMotionMask|ExposureMask| \
|
||||
PointerMotionMask)
|
||||
#define MenuGrabMask (ButtonMask|ButtonMotionMask|StructureNotifyMask|\
|
||||
PointerMotionMask)
|
||||
#define PROMPT_SCHAR '<27>'
|
||||
#define PROMPT_ECHAR '<27>'
|
||||
|
||||
@@ -48,7 +43,7 @@ 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 *menu_handle_release(XEvent *, struct menu_ctx *,
|
||||
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 *);
|
||||
@@ -58,8 +53,19 @@ static int menu_calc_entry(struct screen_ctx *, struct menu_ctx *,
|
||||
void
|
||||
menu_init(struct screen_ctx *sc)
|
||||
{
|
||||
sc->menuwin = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0,
|
||||
1, 1, 1, sc->blackpixl, sc->whitepixl);
|
||||
XGCValues gv;
|
||||
|
||||
sc->menuwin = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, 1, 1, 0,
|
||||
sc->color[CWM_COLOR_BG_MENU].pixel,
|
||||
sc->color[CWM_COLOR_BG_MENU].pixel);
|
||||
|
||||
gv.foreground =
|
||||
sc->color[CWM_COLOR_FG_MENU].pixel^sc->color[CWM_COLOR_BG_MENU].pixel;
|
||||
gv.background = sc->color[CWM_COLOR_BG_MENU].pixel;
|
||||
gv.function = GXxor;
|
||||
|
||||
sc->gc = XCreateGC(X_Dpy, sc->menuwin,
|
||||
GCForeground|GCBackground|GCFunction, &gv);
|
||||
}
|
||||
|
||||
struct menu *
|
||||
@@ -73,7 +79,7 @@ menu_filter(struct menu_q *menuq, char *prompt, char *initial, int dummy,
|
||||
struct menu *mi = NULL;
|
||||
XEvent e;
|
||||
Window focuswin;
|
||||
int Mask, focusrevert;
|
||||
int evmask, focusrevert;
|
||||
|
||||
sc = screen_current();
|
||||
|
||||
@@ -84,11 +90,11 @@ menu_filter(struct menu_q *menuq, char *prompt, char *initial, int dummy,
|
||||
xu_ptr_getpos(sc->rootwin, &mc.x, &mc.y);
|
||||
|
||||
if (prompt == NULL) {
|
||||
Mask = MenuMask;
|
||||
evmask = MenuMask;
|
||||
mc.promptstr[0] = '\0';
|
||||
mc.list = 1;
|
||||
} else {
|
||||
Mask = MenuMask | KeyMask; /* only accept keys if prompt */
|
||||
evmask = MenuMask | KeyMask; /* only accept keys if prompt */
|
||||
snprintf(mc.promptstr, sizeof(mc.promptstr), "%s%c", prompt,
|
||||
PROMPT_SCHAR);
|
||||
snprintf(mc.dispstr, sizeof(mc.dispstr), "%s%s%c", mc.promptstr,
|
||||
@@ -108,7 +114,7 @@ menu_filter(struct menu_q *menuq, char *prompt, char *initial, int dummy,
|
||||
|
||||
XMoveResizeWindow(X_Dpy, sc->menuwin, mc.x, mc.y, mc.width,
|
||||
font_height());
|
||||
XSelectInput(X_Dpy, sc->menuwin, Mask);
|
||||
XSelectInput(X_Dpy, sc->menuwin, evmask);
|
||||
XMapRaised(X_Dpy, sc->menuwin);
|
||||
|
||||
if (xu_ptr_grab(sc->menuwin, MenuGrabMask, Cursor_question) < 0) {
|
||||
@@ -126,7 +132,7 @@ menu_filter(struct menu_q *menuq, char *prompt, char *initial, int dummy,
|
||||
for (;;) {
|
||||
mc.changed = 0;
|
||||
|
||||
XWindowEvent(X_Dpy, sc->menuwin, Mask, &e);
|
||||
XWindowEvent(X_Dpy, sc->menuwin, evmask, &e);
|
||||
|
||||
switch (e.type) {
|
||||
default:
|
||||
@@ -150,7 +156,7 @@ menu_filter(struct menu_q *menuq, char *prompt, char *initial, int dummy,
|
||||
}
|
||||
}
|
||||
out:
|
||||
if ((dummy == 0 && mi->dummy) || (mi->text[0] == '\0')) { /* no match */
|
||||
if (dummy == 0 && mi->dummy) { /* no match */
|
||||
xfree (mi);
|
||||
mi = NULL;
|
||||
xu_ptr_ungrab();
|
||||
@@ -343,7 +349,7 @@ menu_draw(struct screen_ctx *sc, struct menu_ctx *mc, struct menu_q *menuq,
|
||||
0, 0, mc->width, font_height());
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
menu_handle_move(XEvent *e, struct menu_ctx *mc, struct screen_ctx *sc)
|
||||
{
|
||||
mc->prev = mc->entry;
|
||||
@@ -360,7 +366,7 @@ menu_handle_move(XEvent *e, struct menu_ctx *mc, struct screen_ctx *sc)
|
||||
xu_ptr_regrab(MenuGrabMask, Cursor_default);
|
||||
}
|
||||
|
||||
struct menu *
|
||||
static struct menu *
|
||||
menu_handle_release(XEvent *e, struct menu_ctx *mc, struct screen_ctx *sc,
|
||||
struct menu_q *resultq)
|
||||
{
|
||||
@@ -377,7 +383,7 @@ menu_handle_release(XEvent *e, struct menu_ctx *mc, struct screen_ctx *sc,
|
||||
if (entry == i++)
|
||||
break;
|
||||
if (mi == NULL) {
|
||||
XMALLOC(mi, struct menu);
|
||||
mi = xmalloc(sizeof(*mi));
|
||||
mi->text[0] = '\0';
|
||||
mi->dummy = 1;
|
||||
}
|
||||
|
91
mousefunc.c
91
mousefunc.c
@@ -22,14 +22,11 @@
|
||||
#include "headers.h"
|
||||
#include "calmwm.h"
|
||||
|
||||
static int _mousefunc_sweep_calc(struct client_ctx *, int, int, int, int);
|
||||
static void _mousefunc_sweep_draw(struct client_ctx *, int, int);
|
||||
|
||||
#define ADJUST_HEIGHT(cc, dy) ((cc->geom.height - cc->geom.min_dy) / dy)
|
||||
#define ADJUST_WIDTH(cc, dx) ((cc->geom.width - cc->geom.min_dx) / dx)
|
||||
static int mousefunc_sweep_calc(struct client_ctx *, int, int, int, int);
|
||||
static void mousefunc_sweep_draw(struct client_ctx *);
|
||||
|
||||
static int
|
||||
_mousefunc_sweep_calc(struct client_ctx *cc, int x, int y, int mx, int my)
|
||||
mousefunc_sweep_calc(struct client_ctx *cc, int x, int y, int mx, int my)
|
||||
{
|
||||
int width = cc->geom.width, height = cc->geom.height;
|
||||
|
||||
@@ -60,49 +57,50 @@ _mousefunc_sweep_calc(struct client_ctx *cc, int x, int y, int mx, int my)
|
||||
}
|
||||
|
||||
static void
|
||||
_mousefunc_sweep_draw(struct client_ctx *cc, int dx, int dy)
|
||||
mousefunc_sweep_draw(struct client_ctx *cc)
|
||||
{
|
||||
struct screen_ctx *sc = CCTOSC(cc);
|
||||
char asize[10]; /* fits "nnnnxnnnn\0" */
|
||||
int wide, height, wide_size, wide_name;
|
||||
int x = cc->geom.x, y = cc->geom.y;
|
||||
int width, height, width_size, width_name;
|
||||
|
||||
snprintf(asize, sizeof(asize), "%dx%d",
|
||||
ADJUST_WIDTH(cc, dx), ADJUST_HEIGHT(cc, dy));
|
||||
wide_size = font_width(asize, strlen(asize)) + 4;
|
||||
wide_name = font_width(cc->name, strlen(cc->name)) + 4;
|
||||
wide = MAX(wide_size, wide_name);
|
||||
(cc->geom.width - cc->geom.min_dx) / cc->size->width_inc,
|
||||
(cc->geom.height - cc->geom.min_dy) / cc->size->height_inc);
|
||||
width_size = font_width(asize, strlen(asize)) + 4;
|
||||
width_name = font_width(cc->name, strlen(cc->name)) + 4;
|
||||
width = MAX(width_size, width_name);
|
||||
height = font_ascent() + font_descent() + 1;
|
||||
|
||||
XMoveResizeWindow(X_Dpy, sc->menuwin, x, y, wide, height * 2);
|
||||
XMoveResizeWindow(X_Dpy, sc->menuwin, cc->geom.x, cc->geom.y,
|
||||
width, height * 2);
|
||||
XMapWindow(X_Dpy, sc->menuwin);
|
||||
XReparentWindow(X_Dpy, sc->menuwin, cc->win, 0, 0);
|
||||
XClearWindow(X_Dpy, sc->menuwin);
|
||||
font_draw(sc, cc->name, strlen(cc->name), sc->menuwin,
|
||||
2, font_ascent() + 1);
|
||||
font_draw(sc, asize, strlen(asize), sc->menuwin,
|
||||
wide / 2 - wide_size / 2, height + font_ascent() + 1);
|
||||
width / 2 - width_size / 2, height + font_ascent() + 1);
|
||||
}
|
||||
|
||||
void
|
||||
mousefunc_window_resize(struct client_ctx *cc, void *arg)
|
||||
{
|
||||
XEvent ev;
|
||||
Time time = 0;
|
||||
struct screen_ctx *sc = CCTOSC(cc);
|
||||
int dx, dy;
|
||||
int x = cc->geom.x, y = cc->geom.y;
|
||||
|
||||
dx = MAX(1, cc->size->width_inc);
|
||||
dy = MAX(1, cc->size->height_inc);
|
||||
cc->size->width_inc = MAX(1, cc->size->width_inc);
|
||||
cc->size->height_inc = MAX(1, cc->size->height_inc);
|
||||
|
||||
client_raise(cc);
|
||||
client_ptrsave(cc);
|
||||
|
||||
if (xu_ptr_grab(sc->rootwin, MouseMask, Cursor_resize) < 0)
|
||||
if (xu_ptr_grab(cc->win, MouseMask, Cursor_resize) < 0)
|
||||
return;
|
||||
|
||||
xu_ptr_setpos(cc->win, cc->geom.width, cc->geom.height);
|
||||
_mousefunc_sweep_draw(cc, dx, dy);
|
||||
mousefunc_sweep_draw(cc);
|
||||
|
||||
for (;;) {
|
||||
XMaskEvent(X_Dpy, MouseMask|ExposureMask, &ev);
|
||||
@@ -112,13 +110,23 @@ 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, ev.xmotion.y))
|
||||
if (mousefunc_sweep_calc(cc, x, y,
|
||||
ev.xmotion.x_root, ev.xmotion.y_root))
|
||||
/* Recompute window output */
|
||||
_mousefunc_sweep_draw(cc, dx, dy);
|
||||
client_resize(cc);
|
||||
mousefunc_sweep_draw(cc);
|
||||
|
||||
/* don't sync more than 60 times / second */
|
||||
if ((ev.xmotion.time - time) > (1000 / 60)) {
|
||||
time = ev.xmotion.time;
|
||||
XSync(X_Dpy, False);
|
||||
client_resize(cc);
|
||||
}
|
||||
break;
|
||||
case ButtonRelease:
|
||||
if (time) {
|
||||
XSync(X_Dpy, False);
|
||||
client_resize(cc);
|
||||
}
|
||||
XUnmapWindow(X_Dpy, sc->menuwin);
|
||||
XReparentWindow(X_Dpy, sc->menuwin, sc->rootwin, 0, 0);
|
||||
xu_ptr_ungrab();
|
||||
@@ -140,16 +148,15 @@ void
|
||||
mousefunc_window_move(struct client_ctx *cc, void *arg)
|
||||
{
|
||||
XEvent ev;
|
||||
struct screen_ctx *sc = CCTOSC(cc);
|
||||
int mx, my;
|
||||
int x = cc->geom.x, y = cc->geom.y;
|
||||
Time time = 0;
|
||||
int px, py;
|
||||
|
||||
client_raise(cc);
|
||||
|
||||
if (xu_ptr_grab(sc->rootwin, MouseMask, Cursor_move) < 0)
|
||||
if (xu_ptr_grab(cc->win, MouseMask, Cursor_move) < 0)
|
||||
return;
|
||||
|
||||
xu_ptr_getpos(sc->rootwin, &mx, &my);
|
||||
xu_ptr_getpos(cc->win, &px, &py);
|
||||
|
||||
for (;;) {
|
||||
XMaskEvent(X_Dpy, MouseMask|ExposureMask, &ev);
|
||||
@@ -159,11 +166,21 @@ mousefunc_window_move(struct client_ctx *cc, void *arg)
|
||||
client_draw_border(cc);
|
||||
break;
|
||||
case MotionNotify:
|
||||
cc->geom.x = x + (ev.xmotion.x - mx);
|
||||
cc->geom.y = y + (ev.xmotion.y - my);
|
||||
client_move(cc);
|
||||
cc->geom.x = ev.xmotion.x_root - px;
|
||||
cc->geom.y = ev.xmotion.y_root - py;
|
||||
|
||||
/* don't sync more than 60 times / second */
|
||||
if ((ev.xmotion.time - time) > (1000 / 60)) {
|
||||
time = ev.xmotion.time;
|
||||
XSync(X_Dpy, False);
|
||||
client_move(cc);
|
||||
}
|
||||
break;
|
||||
case ButtonRelease:
|
||||
if (time) {
|
||||
XSync(X_Dpy, False);
|
||||
client_move(cc);
|
||||
}
|
||||
xu_ptr_ungrab();
|
||||
return;
|
||||
}
|
||||
@@ -209,15 +226,11 @@ mousefunc_menu_unhide(struct client_ctx *cc, void *arg)
|
||||
TAILQ_INIT(&menuq);
|
||||
TAILQ_FOREACH(cc, &Clientq, entry)
|
||||
if (cc->flags & CLIENT_HIDDEN) {
|
||||
if (cc->label != NULL)
|
||||
wname = cc->label;
|
||||
else
|
||||
wname = cc->name;
|
||||
|
||||
wname = (cc->label) ? cc->label : cc->name;
|
||||
if (wname == NULL)
|
||||
continue;
|
||||
|
||||
XCALLOC(mi, struct menu);
|
||||
mi = xcalloc(1, sizeof(*mi));
|
||||
strlcpy(mi->text, wname, sizeof(mi->text));
|
||||
mi->ctx = cc;
|
||||
TAILQ_INSERT_TAIL(&menuq, mi, entry);
|
||||
@@ -251,7 +264,7 @@ mousefunc_menu_cmd(struct client_ctx *cc, void *arg)
|
||||
|
||||
TAILQ_INIT(&menuq);
|
||||
TAILQ_FOREACH(cmd, &Conf.cmdq, entry) {
|
||||
XCALLOC(mi, struct menu);
|
||||
mi = xcalloc(1, sizeof(*mi));
|
||||
strlcpy(mi->text, cmd->label, sizeof(mi->text));
|
||||
mi->ctx = cmd;
|
||||
TAILQ_INSERT_TAIL(&menuq, mi, entry);
|
||||
|
40
parse.y
40
parse.y
@@ -67,6 +67,9 @@ typedef struct {
|
||||
%token FONTNAME STICKY GAP MOUSEBIND
|
||||
%token AUTOGROUP BIND COMMAND IGNORE
|
||||
%token YES NO BORDERWIDTH MOVEAMOUNT
|
||||
%token COLOR
|
||||
%token ACTIVEBORDER INACTIVEBORDER
|
||||
%token GROUPBORDER UNGROUPBORDER
|
||||
%token ERROR
|
||||
%token <v.string> STRING
|
||||
%token <v.number> NUMBER
|
||||
@@ -77,6 +80,7 @@ typedef struct {
|
||||
grammar : /* empty */
|
||||
| grammar '\n'
|
||||
| grammar main '\n'
|
||||
| grammar color '\n'
|
||||
| grammar error '\n' { file->errors++; }
|
||||
;
|
||||
|
||||
@@ -128,7 +132,7 @@ main : FONTNAME STRING {
|
||||
YYERROR;
|
||||
}
|
||||
|
||||
XCALLOC(aw, struct autogroupwin);
|
||||
aw = xcalloc(1, sizeof(*aw));
|
||||
|
||||
if ((p = strchr($3, ',')) == NULL) {
|
||||
aw->name = NULL;
|
||||
@@ -147,7 +151,7 @@ main : FONTNAME STRING {
|
||||
| IGNORE STRING {
|
||||
struct winmatch *wm;
|
||||
|
||||
XCALLOC(wm, struct winmatch);
|
||||
wm = xcalloc(1, sizeof(*wm));
|
||||
strlcpy(wm->title, $2, sizeof(wm->title));
|
||||
TAILQ_INSERT_TAIL(&conf->ignoreq, wm, entry);
|
||||
|
||||
@@ -170,6 +174,27 @@ main : FONTNAME STRING {
|
||||
free($3);
|
||||
}
|
||||
;
|
||||
|
||||
color : COLOR colors
|
||||
;
|
||||
|
||||
colors : ACTIVEBORDER STRING {
|
||||
free(conf->color[CWM_COLOR_BORDOR_ACTIVE].name);
|
||||
conf->color[CWM_COLOR_BORDOR_ACTIVE].name = $2;
|
||||
}
|
||||
| INACTIVEBORDER STRING {
|
||||
free(conf->color[CWM_COLOR_BORDER_INACTIVE].name);
|
||||
conf->color[CWM_COLOR_BORDER_INACTIVE].name = $2;
|
||||
}
|
||||
| GROUPBORDER STRING {
|
||||
free(conf->color[CWM_COLOR_BORDER_GROUP].name);
|
||||
conf->color[CWM_COLOR_BORDER_GROUP].name = $2;
|
||||
}
|
||||
| UNGROUPBORDER STRING {
|
||||
free(conf->color[CWM_COLOR_BORDER_UNGROUP].name);
|
||||
conf->color[CWM_COLOR_BORDER_UNGROUP].name = $2;
|
||||
}
|
||||
;
|
||||
%%
|
||||
|
||||
struct keywords {
|
||||
@@ -202,17 +227,22 @@ lookup(char *s)
|
||||
{
|
||||
/* this has to be sorted always */
|
||||
static const struct keywords keywords[] = {
|
||||
{ "activeborder", ACTIVEBORDER},
|
||||
{ "autogroup", AUTOGROUP},
|
||||
{ "bind", BIND},
|
||||
{ "borderwidth", BORDERWIDTH},
|
||||
{ "color", COLOR},
|
||||
{ "command", COMMAND},
|
||||
{ "fontname", FONTNAME},
|
||||
{ "gap", GAP},
|
||||
{ "groupborder", GROUPBORDER},
|
||||
{ "ignore", IGNORE},
|
||||
{ "inactiveborder", INACTIVEBORDER},
|
||||
{ "mousebind", MOUSEBIND},
|
||||
{ "moveamount", MOVEAMOUNT},
|
||||
{ "no", NO},
|
||||
{ "sticky", STICKY},
|
||||
{ "ungroupborder", UNGROUPBORDER},
|
||||
{ "yes", YES}
|
||||
};
|
||||
const struct keywords *p;
|
||||
@@ -473,7 +503,7 @@ parse_config(const char *filename, struct conf *xconf)
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
XCALLOC(conf, struct conf);
|
||||
conf = xcalloc(1, sizeof(*conf));
|
||||
|
||||
if ((file = pushfile(filename)) == NULL) {
|
||||
free(conf);
|
||||
@@ -498,6 +528,7 @@ parse_config(const char *filename, struct conf *xconf)
|
||||
struct winmatch *wm;
|
||||
struct cmd *cmd;
|
||||
struct mousebinding *mb;
|
||||
int i;
|
||||
|
||||
conf_clear(xconf);
|
||||
|
||||
@@ -535,6 +566,9 @@ parse_config(const char *filename, struct conf *xconf)
|
||||
strlcpy(xconf->lockpath, conf->lockpath,
|
||||
sizeof(xconf->lockpath));
|
||||
|
||||
for (i = 0; i < CWM_COLOR_MAX; i++)
|
||||
xconf->color[i].name = conf->color[i].name;
|
||||
|
||||
xconf->DefaultFontName = conf->DefaultFontName;
|
||||
|
||||
bcopy(&(conf->gap_top), &(xconf->gap_top), sizeof(int) * 4);
|
||||
|
7
screen.c
7
screen.c
@@ -21,9 +21,14 @@
|
||||
#include "headers.h"
|
||||
#include "calmwm.h"
|
||||
|
||||
extern struct screen_ctx_q Screenq;
|
||||
extern struct screen_ctx *Curscreen;
|
||||
|
||||
void
|
||||
screen_init(void)
|
||||
{
|
||||
TAILQ_INIT(&Screenq);
|
||||
}
|
||||
|
||||
struct screen_ctx *
|
||||
screen_fromroot(Window rootwin)
|
||||
{
|
||||
|
20
search.c
20
search.c
@@ -17,12 +17,11 @@
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <fnmatch.h>
|
||||
#include "headers.h"
|
||||
#include "calmwm.h"
|
||||
|
||||
#define SearchMask (KeyPressMask|ExposureMask)
|
||||
|
||||
static int _strsubmatch(char *, char *, int);
|
||||
static int strsubmatch(char *, char *, int);
|
||||
|
||||
/*
|
||||
* Match: label, title, class.
|
||||
@@ -54,7 +53,7 @@ search_match_client(struct menu_q *menuq, struct menu_q *resultq, char *search)
|
||||
struct client_ctx *cc = mi->ctx;
|
||||
|
||||
/* First, try to match on labels. */
|
||||
if (cc->label != NULL && _strsubmatch(search, cc->label, 0)) {
|
||||
if (cc->label != NULL && strsubmatch(search, cc->label, 0)) {
|
||||
cc->matchname = cc->label;
|
||||
tier = 0;
|
||||
}
|
||||
@@ -62,7 +61,7 @@ search_match_client(struct menu_q *menuq, struct menu_q *resultq, char *search)
|
||||
/* Then, on window names. */
|
||||
if (tier < 0) {
|
||||
TAILQ_FOREACH_REVERSE(wn, &cc->nameq, winname_q, entry)
|
||||
if (_strsubmatch(search, wn->name, 0)) {
|
||||
if (strsubmatch(search, wn->name, 0)) {
|
||||
cc->matchname = wn->name;
|
||||
tier = 2;
|
||||
break;
|
||||
@@ -74,7 +73,7 @@ search_match_client(struct menu_q *menuq, struct menu_q *resultq, char *search)
|
||||
* name.
|
||||
*/
|
||||
|
||||
if (tier < 0 && _strsubmatch(search, cc->app_class, 0)) {
|
||||
if (tier < 0 && strsubmatch(search, cc->app_class, 0)) {
|
||||
cc->matchname = cc->app_class;
|
||||
tier = 3;
|
||||
}
|
||||
@@ -168,7 +167,7 @@ search_match_text(struct menu_q *menuq, struct menu_q *resultq, char *search)
|
||||
TAILQ_INIT(resultq);
|
||||
|
||||
TAILQ_FOREACH(mi, menuq, entry)
|
||||
if (_strsubmatch(search, mi->text, 0))
|
||||
if (strsubmatch(search, mi->text, 0))
|
||||
TAILQ_INSERT_TAIL(resultq, mi, resultentry);
|
||||
}
|
||||
|
||||
@@ -180,8 +179,9 @@ search_match_exec(struct menu_q *menuq, struct menu_q *resultq, char *search)
|
||||
TAILQ_INIT(resultq);
|
||||
|
||||
TAILQ_FOREACH(mi, menuq, entry) {
|
||||
if (_strsubmatch(search, mi->text, 1) == 0)
|
||||
continue;
|
||||
if (strsubmatch(search, mi->text, 1) == 0 &&
|
||||
fnmatch(search, mi->text, 0) == FNM_NOMATCH)
|
||||
continue;
|
||||
for (mj = TAILQ_FIRST(resultq); mj != NULL;
|
||||
mj = TAILQ_NEXT(mj, resultentry)) {
|
||||
if (strcasecmp(mi->text, mj->text) < 0) {
|
||||
@@ -195,7 +195,7 @@ search_match_exec(struct menu_q *menuq, struct menu_q *resultq, char *search)
|
||||
}
|
||||
|
||||
static int
|
||||
_strsubmatch(char *sub, char *str, int zeroidx)
|
||||
strsubmatch(char *sub, char *str, int zeroidx)
|
||||
{
|
||||
size_t len, sublen;
|
||||
u_int n, flen;
|
||||
|
291
xevents.c
291
xevents.c
@@ -27,13 +27,42 @@
|
||||
#include "headers.h"
|
||||
#include "calmwm.h"
|
||||
|
||||
/*
|
||||
* NOTE: in reality, many of these should move to client.c now that
|
||||
* we've got this nice event layer.
|
||||
*/
|
||||
static void xev_handle_maprequest(XEvent *);
|
||||
static void xev_handle_unmapnotify(XEvent *);
|
||||
static void xev_handle_destroynotify(XEvent *);
|
||||
static void xev_handle_configurerequest(XEvent *);
|
||||
static void xev_handle_propertynotify(XEvent *);
|
||||
static void xev_handle_enternotify(XEvent *);
|
||||
static void xev_handle_leavenotify(XEvent *);
|
||||
static void xev_handle_buttonpress(XEvent *);
|
||||
static void xev_handle_buttonrelease(XEvent *);
|
||||
static void xev_handle_keypress(XEvent *);
|
||||
static void xev_handle_keyrelease(XEvent *);
|
||||
static void xev_handle_expose(XEvent *);
|
||||
static void xev_handle_clientmessage(XEvent *);
|
||||
static void xev_handle_randr(XEvent *);
|
||||
static void xev_handle_mappingnotify(XEvent *);
|
||||
|
||||
void
|
||||
xev_handle_maprequest(struct xevent *xev, XEvent *ee)
|
||||
|
||||
void (*xev_handlers[LASTEvent])(XEvent *) = {
|
||||
[MapRequest] = xev_handle_maprequest,
|
||||
[UnmapNotify] = xev_handle_unmapnotify,
|
||||
[ConfigureRequest] = xev_handle_configurerequest,
|
||||
[PropertyNotify] = xev_handle_propertynotify,
|
||||
[EnterNotify] = xev_handle_enternotify,
|
||||
[LeaveNotify] = xev_handle_leavenotify,
|
||||
[ButtonPress] = xev_handle_buttonpress,
|
||||
[ButtonRelease] = xev_handle_buttonrelease,
|
||||
[KeyPress] = xev_handle_keypress,
|
||||
[KeyRelease] = xev_handle_keyrelease,
|
||||
[Expose] = xev_handle_expose,
|
||||
[DestroyNotify] = xev_handle_destroynotify,
|
||||
[ClientMessage] = xev_handle_clientmessage,
|
||||
[MappingNotify] = xev_handle_mappingnotify,
|
||||
};
|
||||
|
||||
static void
|
||||
xev_handle_maprequest(XEvent *ee)
|
||||
{
|
||||
XMapRequestEvent *e = &ee->xmaprequest;
|
||||
struct client_ctx *cc = NULL, *old_cc;
|
||||
@@ -48,11 +77,10 @@ xev_handle_maprequest(struct xevent *xev, XEvent *ee)
|
||||
}
|
||||
|
||||
client_ptrwarp(cc);
|
||||
xev_register(xev);
|
||||
}
|
||||
|
||||
void
|
||||
xev_handle_unmapnotify(struct xevent *xev, XEvent *ee)
|
||||
static void
|
||||
xev_handle_unmapnotify(XEvent *ee)
|
||||
{
|
||||
XUnmapEvent *e = &ee->xunmap;
|
||||
XEvent ev;
|
||||
@@ -76,24 +104,20 @@ xev_handle_unmapnotify(struct xevent *xev, XEvent *ee)
|
||||
client_hide(cc);
|
||||
}
|
||||
XUngrabServer(X_Dpy);
|
||||
|
||||
xev_register(xev);
|
||||
}
|
||||
|
||||
void
|
||||
xev_handle_destroynotify(struct xevent *xev, XEvent *ee)
|
||||
static void
|
||||
xev_handle_destroynotify(XEvent *ee)
|
||||
{
|
||||
XDestroyWindowEvent *e = &ee->xdestroywindow;
|
||||
struct client_ctx *cc;
|
||||
|
||||
if ((cc = client_find(e->window)) != NULL)
|
||||
client_delete(cc);
|
||||
|
||||
xev_register(xev);
|
||||
}
|
||||
|
||||
void
|
||||
xev_handle_configurerequest(struct xevent *xev, XEvent *ee)
|
||||
static void
|
||||
xev_handle_configurerequest(XEvent *ee)
|
||||
{
|
||||
XConfigureRequestEvent *e = &ee->xconfigurerequest;
|
||||
struct client_ctx *cc;
|
||||
@@ -140,12 +164,10 @@ xev_handle_configurerequest(struct xevent *xev, XEvent *ee)
|
||||
|
||||
XConfigureWindow(X_Dpy, e->window, e->value_mask, &wc);
|
||||
}
|
||||
|
||||
xev_register(xev);
|
||||
}
|
||||
|
||||
void
|
||||
xev_handle_propertynotify(struct xevent *xev, XEvent *ee)
|
||||
static void
|
||||
xev_handle_propertynotify(XEvent *ee)
|
||||
{
|
||||
XPropertyEvent *e = &ee->xproperty;
|
||||
struct client_ctx *cc;
|
||||
@@ -164,8 +186,6 @@ xev_handle_propertynotify(struct xevent *xev, XEvent *ee)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
xev_register(xev);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -187,29 +207,25 @@ xev_reconfig(struct client_ctx *cc)
|
||||
XSendEvent(X_Dpy, cc->win, False, StructureNotifyMask, (XEvent *)&ce);
|
||||
}
|
||||
|
||||
void
|
||||
xev_handle_enternotify(struct xevent *xev, XEvent *ee)
|
||||
static void
|
||||
xev_handle_enternotify(XEvent *ee)
|
||||
{
|
||||
XCrossingEvent *e = &ee->xcrossing;
|
||||
struct client_ctx *cc;
|
||||
|
||||
if ((cc = client_find(e->window)) != NULL)
|
||||
client_setactive(cc, 1);
|
||||
|
||||
xev_register(xev);
|
||||
}
|
||||
|
||||
void
|
||||
xev_handle_leavenotify(struct xevent *xev, XEvent *ee)
|
||||
static void
|
||||
xev_handle_leavenotify(XEvent *ee)
|
||||
{
|
||||
client_leave(NULL);
|
||||
|
||||
xev_register(xev);
|
||||
}
|
||||
|
||||
/* We can split this into two event handlers. */
|
||||
void
|
||||
xev_handle_buttonpress(struct xevent *xev, XEvent *ee)
|
||||
static void
|
||||
xev_handle_buttonpress(XEvent *ee)
|
||||
{
|
||||
XButtonEvent *e = &ee->xbutton;
|
||||
struct client_ctx *cc;
|
||||
@@ -228,35 +244,31 @@ xev_handle_buttonpress(struct xevent *xev, XEvent *ee)
|
||||
}
|
||||
|
||||
if (mb == NULL)
|
||||
goto out;
|
||||
return;
|
||||
|
||||
if (mb->context == MOUSEBIND_CTX_ROOT) {
|
||||
if (e->window != sc->rootwin)
|
||||
goto out;
|
||||
return;
|
||||
} else if (mb->context == MOUSEBIND_CTX_WIN) {
|
||||
cc = client_find(e->window);
|
||||
if (cc == NULL)
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
|
||||
(*mb->callback)(cc, e);
|
||||
out:
|
||||
xev_register(xev);
|
||||
}
|
||||
|
||||
void
|
||||
xev_handle_buttonrelease(struct xevent *xev, XEvent *ee)
|
||||
static void
|
||||
xev_handle_buttonrelease(XEvent *ee)
|
||||
{
|
||||
struct client_ctx *cc;
|
||||
|
||||
if ((cc = client_current()) != NULL)
|
||||
group_sticky_toggle_exit(cc);
|
||||
|
||||
xev_register(xev);
|
||||
}
|
||||
|
||||
void
|
||||
xev_handle_keypress(struct xevent *xev, XEvent *ee)
|
||||
static void
|
||||
xev_handle_keypress(XEvent *ee)
|
||||
{
|
||||
XKeyEvent *e = &ee->xkey;
|
||||
struct client_ctx *cc = NULL;
|
||||
@@ -286,25 +298,22 @@ xev_handle_keypress(struct xevent *xev, XEvent *ee)
|
||||
}
|
||||
|
||||
if (kb == NULL)
|
||||
goto out;
|
||||
return;
|
||||
|
||||
if ((kb->flags & (KBFLAG_NEEDCLIENT)) &&
|
||||
(cc = client_find(e->window)) == NULL &&
|
||||
(cc = client_current()) == NULL)
|
||||
if (kb->flags & KBFLAG_NEEDCLIENT)
|
||||
goto out;
|
||||
return;
|
||||
|
||||
(*kb->callback)(cc, &kb->argument);
|
||||
|
||||
out:
|
||||
xev_register(xev);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is only used for the alt suppression detection.
|
||||
*/
|
||||
void
|
||||
xev_handle_keyrelease(struct xevent *xev, XEvent *ee)
|
||||
static void
|
||||
xev_handle_keyrelease(XEvent *ee)
|
||||
{
|
||||
XKeyEvent *e = &ee->xkey;
|
||||
struct screen_ctx *sc;
|
||||
@@ -316,7 +325,7 @@ xev_handle_keyrelease(struct xevent *xev, XEvent *ee)
|
||||
|
||||
keysym = XKeycodeToKeysym(X_Dpy, e->keycode, 0);
|
||||
if (keysym != XK_Alt_L && keysym != XK_Alt_R)
|
||||
goto out;
|
||||
return;
|
||||
|
||||
sc->altpersist = 0;
|
||||
|
||||
@@ -330,13 +339,10 @@ xev_handle_keyrelease(struct xevent *xev, XEvent *ee)
|
||||
group_sticky_toggle_exit(cc);
|
||||
XUngrabKeyboard(X_Dpy, CurrentTime);
|
||||
}
|
||||
|
||||
out:
|
||||
xev_register(xev);
|
||||
}
|
||||
|
||||
void
|
||||
xev_handle_clientmessage(struct xevent *xev, XEvent *ee)
|
||||
static void
|
||||
xev_handle_clientmessage(XEvent *ee)
|
||||
{
|
||||
XClientMessageEvent *e = &ee->xclient;
|
||||
Atom xa_wm_change_state;
|
||||
@@ -345,28 +351,28 @@ xev_handle_clientmessage(struct xevent *xev, XEvent *ee)
|
||||
xa_wm_change_state = XInternAtom(X_Dpy, "WM_CHANGE_STATE", False);
|
||||
|
||||
if ((cc = client_find(e->window)) == NULL)
|
||||
goto out;
|
||||
return;
|
||||
|
||||
if (e->message_type == xa_wm_change_state && e->format == 32 &&
|
||||
e->data.l[0] == IconicState)
|
||||
client_hide(cc);
|
||||
out:
|
||||
xev_register(xev);
|
||||
}
|
||||
|
||||
void
|
||||
xev_handle_randr(struct xevent *xev, XEvent *ee)
|
||||
static void
|
||||
xev_handle_randr(XEvent *ee)
|
||||
{
|
||||
XRRScreenChangeNotifyEvent *rev = (XRRScreenChangeNotifyEvent *)ee;
|
||||
struct client_ctx *cc;
|
||||
struct screen_ctx *sc;
|
||||
int i;
|
||||
|
||||
if ((cc = client_find(rev->window)) != NULL) {
|
||||
XRRUpdateConfiguration(ee);
|
||||
sc = CCTOSC(cc);
|
||||
sc->xmax = rev->width;
|
||||
sc->ymax = rev->height;
|
||||
screen_init_xinerama(sc);
|
||||
i = XRRRootToScreen(X_Dpy, rev->root);
|
||||
TAILQ_FOREACH(sc, &Screenq, entry) {
|
||||
if (sc->which == (u_int)i) {
|
||||
XRRUpdateConfiguration(ee);
|
||||
sc->xmax = rev->width;
|
||||
sc->ymax = rev->height;
|
||||
screen_init_xinerama(sc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,8 +380,8 @@ xev_handle_randr(struct xevent *xev, XEvent *ee)
|
||||
* Called when the keymap has changed.
|
||||
* Ungrab all keys, reload keymap and then regrab
|
||||
*/
|
||||
void
|
||||
xev_handle_mapping(struct xevent *xev, XEvent *ee)
|
||||
static void
|
||||
xev_handle_mappingnotify(XEvent *ee)
|
||||
{
|
||||
XMappingEvent *e = &ee->xmapping;
|
||||
struct keybinding *kb;
|
||||
@@ -387,160 +393,31 @@ xev_handle_mapping(struct xevent *xev, XEvent *ee)
|
||||
|
||||
TAILQ_FOREACH(kb, &Conf.keybindingq, entry)
|
||||
conf_grab(&Conf, kb);
|
||||
|
||||
xev_register(xev);
|
||||
}
|
||||
|
||||
/*
|
||||
* X Event handling
|
||||
*/
|
||||
|
||||
static struct xevent_q _xevq, _xevq_putaway;
|
||||
static short _xev_q_lock = 0;
|
||||
volatile sig_atomic_t _xev_quit = 0;
|
||||
|
||||
void
|
||||
xev_init(void)
|
||||
{
|
||||
TAILQ_INIT(&_xevq);
|
||||
TAILQ_INIT(&_xevq_putaway);
|
||||
}
|
||||
|
||||
struct xevent *
|
||||
xev_new(Window *win, Window *root,
|
||||
int type, void (*cb)(struct xevent *, XEvent *), void *arg)
|
||||
{
|
||||
struct xevent *xev;
|
||||
|
||||
XMALLOC(xev, struct xevent);
|
||||
xev->xev_win = win;
|
||||
xev->xev_root = root;
|
||||
xev->xev_type = type;
|
||||
xev->xev_cb = cb;
|
||||
xev->xev_arg = arg;
|
||||
|
||||
return (xev);
|
||||
}
|
||||
|
||||
void
|
||||
xev_register(struct xevent *xev)
|
||||
{
|
||||
struct xevent_q *xq;
|
||||
|
||||
xq = _xev_q_lock ? &_xevq_putaway : &_xevq;
|
||||
TAILQ_INSERT_TAIL(xq, xev, entry);
|
||||
}
|
||||
|
||||
void
|
||||
_xev_reincorporate(void)
|
||||
{
|
||||
struct xevent *xev;
|
||||
|
||||
while ((xev = TAILQ_FIRST(&_xevq_putaway)) != NULL) {
|
||||
TAILQ_REMOVE(&_xevq_putaway, xev, entry);
|
||||
TAILQ_INSERT_TAIL(&_xevq, xev, entry);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
xev_handle_expose(struct xevent *xev, XEvent *ee)
|
||||
static void
|
||||
xev_handle_expose(XEvent *ee)
|
||||
{
|
||||
XExposeEvent *e = &ee->xexpose;
|
||||
struct client_ctx *cc;
|
||||
|
||||
if ((cc = client_find(e->window)) != NULL && e->count == 0)
|
||||
client_draw_border(cc);
|
||||
|
||||
xev_register(xev);
|
||||
}
|
||||
|
||||
#define ASSIGN(xtype) do { \
|
||||
root = e. xtype .root; \
|
||||
win = e. xtype .window; \
|
||||
} while (0)
|
||||
|
||||
#define ASSIGN1(xtype) do { \
|
||||
win = e. xtype .window; \
|
||||
} while (0)
|
||||
volatile sig_atomic_t _xev_quit = 0;
|
||||
|
||||
void
|
||||
xev_loop(void)
|
||||
{
|
||||
Window win, root;
|
||||
XEvent e;
|
||||
struct xevent *xev = NULL, *nextxev;
|
||||
int type;
|
||||
|
||||
while (_xev_quit == 0) {
|
||||
#ifdef DIAGNOSTIC
|
||||
if (TAILQ_EMPTY(&_xevq))
|
||||
errx(1, "X event queue empty");
|
||||
#endif
|
||||
|
||||
XNextEvent(X_Dpy, &e);
|
||||
type = e.type;
|
||||
|
||||
win = root = 0;
|
||||
|
||||
switch (type) {
|
||||
case MapRequest:
|
||||
ASSIGN1(xmaprequest);
|
||||
break;
|
||||
case UnmapNotify:
|
||||
ASSIGN1(xunmap);
|
||||
break;
|
||||
case ConfigureRequest:
|
||||
ASSIGN1(xconfigurerequest);
|
||||
break;
|
||||
case PropertyNotify:
|
||||
ASSIGN1(xproperty);
|
||||
break;
|
||||
case EnterNotify:
|
||||
case LeaveNotify:
|
||||
ASSIGN(xcrossing);
|
||||
break;
|
||||
case ButtonPress:
|
||||
ASSIGN(xbutton);
|
||||
break;
|
||||
case ButtonRelease:
|
||||
ASSIGN(xbutton);
|
||||
break;
|
||||
case KeyPress:
|
||||
case KeyRelease:
|
||||
ASSIGN(xkey);
|
||||
break;
|
||||
case DestroyNotify:
|
||||
ASSIGN1(xdestroywindow);
|
||||
break;
|
||||
case ClientMessage:
|
||||
ASSIGN1(xclient);
|
||||
break;
|
||||
default:
|
||||
if (e.type == Randr_ev)
|
||||
xev_handle_randr(xev, &e);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now, search for matches, and call each of them.
|
||||
*/
|
||||
_xev_q_lock = 1;
|
||||
for (xev = TAILQ_FIRST(&_xevq); xev != NULL; xev = nextxev) {
|
||||
nextxev = TAILQ_NEXT(xev, entry);
|
||||
|
||||
if ((type != xev->xev_type && xev->xev_type != 0) ||
|
||||
(xev->xev_win != NULL && win != *xev->xev_win) ||
|
||||
(xev->xev_root != NULL && root != *xev->xev_root))
|
||||
continue;
|
||||
|
||||
TAILQ_REMOVE(&_xevq, xev, entry);
|
||||
|
||||
(*xev->xev_cb)(xev, &e);
|
||||
}
|
||||
_xev_q_lock = 0;
|
||||
_xev_reincorporate();
|
||||
if (e.type - Randr_ev == RRScreenChangeNotify)
|
||||
xev_handle_randr(&e);
|
||||
else if (e.type < LASTEvent && xev_handlers[e.type] != NULL)
|
||||
(*xev_handlers[e.type])(&e);
|
||||
}
|
||||
}
|
||||
|
||||
#undef ASSIGN
|
||||
#undef ASSIGN1
|
||||
|
26
xutil.c
26
xutil.c
@@ -21,7 +21,7 @@
|
||||
#include "headers.h"
|
||||
#include "calmwm.h"
|
||||
|
||||
unsigned int ign_mods[] = { 0, LockMask, Mod2Mask, Mod2Mask | LockMask };
|
||||
static unsigned int ign_mods[] = { 0, LockMask, Mod2Mask, Mod2Mask | LockMask };
|
||||
|
||||
int
|
||||
xu_ptr_grab(Window win, int mask, Cursor curs)
|
||||
@@ -161,8 +161,8 @@ xu_setstate(struct client_ctx *cc, int state)
|
||||
{
|
||||
long dat[2];
|
||||
|
||||
dat[0] = (long)state;
|
||||
dat[1] = (long)None;
|
||||
dat[0] = state;
|
||||
dat[1] = None;
|
||||
|
||||
cc->state = state;
|
||||
XChangeProperty(X_Dpy, cc->win, WM_STATE, WM_STATE, 32,
|
||||
@@ -184,3 +184,23 @@ xu_getatoms(void)
|
||||
{
|
||||
XInternAtoms(X_Dpy, atoms, CWM_NO_ATOMS, False, cwm_atoms);
|
||||
}
|
||||
|
||||
unsigned long
|
||||
xu_getcolor(struct screen_ctx *sc, char *name)
|
||||
{
|
||||
XColor color, tmp;
|
||||
|
||||
if (!XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, sc->which),
|
||||
name, &color, &tmp)) {
|
||||
warnx("XAllocNamedColor error: '%s'", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return color.pixel;
|
||||
}
|
||||
|
||||
void
|
||||
xu_freecolor(struct screen_ctx *sc, unsigned long pixel)
|
||||
{
|
||||
XFreeColors(X_Dpy, DefaultColormap(X_Dpy, sc->which), &pixel, 1, 0L);
|
||||
}
|
||||
|
Reference in New Issue
Block a user