2 Commits

Author SHA1 Message Date
schwarze
a119fe5240 cvsimport 2010-09-25 21:58:18 +00:00
Christian Neukirchen
f2e8fad75c cvsimport 2010-09-25 22:21:23 +00:00
21 changed files with 971 additions and 1109 deletions

View File

@@ -1,47 +1,54 @@
# cwm makefile for BSD make and GNU make # $OpenBSD$
# uses pkg-config, DESTDIR and PREFIX
#.include <bsd.xconf.mk>
PROG= cwm PROG= cwm
PREFIX= /usr/local BINDIR= /usr/bin
SRCS= calmwm.c screen.c xmalloc.c client.c menu.c \ SRCS= calmwm.c screen.c xmalloc.c client.c menu.c \
search.c util.c xutil.c conf.c xevents.c group.c \ search.c util.c xutil.c conf.c input.c xevents.c group.c \
kbfunc.c mousefunc.c font.c parse.y kbfunc.c mousefunc.c font.c parse.y
OBJS= calmwm.o screen.o xmalloc.o client.o menu.o \ OBJS= calmwm.o screen.o xmalloc.o client.o menu.o \
search.o util.o xutil.o conf.o xevents.o group.o \ search.o util.o xutil.o conf.o input.o xevents.o group.o \
kbfunc.o mousefunc.o font.o strlcpy.o strlcat.o y.tab.o \ kbfunc.o mousefunc.o font.o strlcpy.o strlcat.o y.tab.o \
strtonum.o fgetln.o strtonum.o fgetln.o
CPPFLAGS+= `pkg-config --cflags fontconfig x11 xft xinerama xrandr` X11BASE= /usr
CFLAGS= -Wall -O2 -g CPPFLAGS+= -I${X11BASE}/include -I${X11BASE}/include/freetype2 -I.
LDFLAGS+= `pkg-config --libs fontconfig x11 xft xinerama xrandr` CFLAGS+= -Wall
MANPREFIX= ${PREFIX}/share/man LDADD+= -L${X11BASE}/lib -lXft -lXrender -lX11 -lXau -lXdmcp \
-lfontconfig -lexpat -lfreetype -lz -lXinerama -lXrandr -lXext
all: ${PROG} MANDIR= ${X11BASE}/man/cat
MAN= cwm.1 cwmrc.5
CLEANFILES= cwm.cat1 cwmrc.cat5
all: $(PROG)
clean: clean:
rm -rf ${OBJS} ${PROG} y.tab.c rm -rf $(OBJS) $(PROG) y.tab.c
y.tab.c: parse.y y.tab.c: parse.y
yacc parse.y byacc parse.y
${PROG}: ${OBJS} y.tab.o
${CC} ${OBJS} ${LDFLAGS} -o ${PROG}
.c.o: $(PROG): $(OBJS) y.tab.o
${CC} -c ${CFLAGS} ${CPPFLAGS} $< $(CC) $(OBJS) ${LDADD} -o ${PROG}
$(OBJS): %.o: %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $<
install: ${PROG} install: ${PROG}
install -d ${DESTDIR}${PREFIX}/bin ${DESTDIR}${MANPREFIX}/man1 ${DESTDIR}${MANPREFIX}/man5 install -m 755 cwm /usr/local/bin/
install -m 755 cwm ${DESTDIR}${PREFIX}/bin install -m 644 cwm.1 /usr/local/man/man1
install -m 644 cwm.1 ${DESTDIR}${MANPREFIX}/man1 install -m 644 cwmrc.5 /usr/local/man/man5
install -m 644 cwmrc.5 ${DESTDIR}${MANPREFIX}/man5
release: #.include <bsd.prog.mk>
VERSION=$$(git describe --tags | sed 's/^v//;s/-[^.]*$$//') && \ #.include <bsd.xorg.mk>
git archive --prefix=cwm-$$VERSION/ -o cwm-$$VERSION.tar.gz HEAD

24
README
View File

@@ -1,24 +0,0 @@
This is a port of OpenBSD's excellent cwm[0] to Linux and other
Unices.
cwm is a window manager for X11 which contains many features that
concentrate on the efficiency and transparency of window
management. cwm also aims to maintain the simplest and most
pleasant aesthetic.
This port requires pkg-config, Xft, Xinerama and Xrandr. The included
Makefile should work with both GNU make and BSD make.
This version actively tracks changes in the OpenBSD CVS repository.
Releases are roughly coordinated.
The revision controlled version is at https://github.com/chneukirchen/cwm
Releases can be found at http://chneukirchen.org/releases
ChangeLog:
2012-05-02: First public release 5.1 of portable cwm.
--Christian Neukirchen <chneukirchen@gmail.com>
[0]: http://www.openbsd.org/cgi-bin/cvsweb/xenocara/app/cwm/

View File

@@ -15,7 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $OpenBSD$ * $Id$
*/ */
#include <sys/param.h> #include <sys/param.h>
@@ -35,22 +35,22 @@
Display *X_Dpy; Display *X_Dpy;
Cursor Cursor_default;
Cursor Cursor_move; Cursor Cursor_move;
Cursor Cursor_normal;
Cursor Cursor_question;
Cursor Cursor_resize; Cursor Cursor_resize;
Cursor Cursor_select;
Cursor Cursor_default;
Cursor Cursor_question;
struct screen_ctx_q Screenq = TAILQ_HEAD_INITIALIZER(Screenq); struct screen_ctx_q Screenq = TAILQ_HEAD_INITIALIZER(Screenq);
struct client_ctx_q Clientq = TAILQ_HEAD_INITIALIZER(Clientq); struct client_ctx_q Clientq = TAILQ_HEAD_INITIALIZER(Clientq);
int HasXinerama, HasRandr, Randr_ev; int HasXinerama, HasRandr, Randr_ev;
int Starting;
struct conf Conf; struct conf Conf;
static void sigchld_cb(int); static void sigchld_cb(int);
static void dpy_init(const char *); static void dpy_init(const char *);
static int x_errorhandler(Display *, XErrorEvent *); static int x_errorhandler(Display *, XErrorEvent *);
static int x_wmerrorhandler(Display *, XErrorEvent *);
static void x_setup(void); static void x_setup(void);
static void x_setupscreen(struct screen_ctx *, u_int); static void x_setupscreen(struct screen_ctx *, u_int);
static void x_teardown(void); static void x_teardown(void);
@@ -80,12 +80,14 @@ main(int argc, char **argv)
if (signal(SIGCHLD, sigchld_cb) == SIG_ERR) if (signal(SIGCHLD, sigchld_cb) == SIG_ERR)
err(1, "signal"); err(1, "signal");
Starting = 1;
dpy_init(display_name); dpy_init(display_name);
bzero(&Conf, sizeof(Conf)); bzero(&Conf, sizeof(Conf));
conf_setup(&Conf, conf_file); conf_setup(&Conf, conf_file);
xu_getatoms(); xu_getatoms();
x_setup(); x_setup();
Starting = 0;
xev_loop(); xev_loop();
@@ -99,15 +101,10 @@ dpy_init(const char *dpyname)
{ {
int i; int i;
XSetErrorHandler(x_errorhandler);
if ((X_Dpy = XOpenDisplay(dpyname)) == NULL) if ((X_Dpy = XOpenDisplay(dpyname)) == NULL)
errx(1, "unable to open display \"%s\"", errx(1, "unable to open display \"%s\"",
XDisplayName(dpyname)); XDisplayName(dpyname));
XSetErrorHandler(x_wmerrorhandler);
XSelectInput(X_Dpy, DefaultRootWindow(X_Dpy), SubstructureRedirectMask);
XSync(X_Dpy, False);
XSetErrorHandler(x_errorhandler); XSetErrorHandler(x_errorhandler);
HasRandr = XRRQueryExtension(X_Dpy, &Randr_ev, &i); HasRandr = XRRQueryExtension(X_Dpy, &Randr_ev, &i);
@@ -120,12 +117,6 @@ x_setup(void)
struct keybinding *kb; struct keybinding *kb;
int i; int i;
Cursor_default = XCreateFontCursor(X_Dpy, XC_X_cursor);
Cursor_move = XCreateFontCursor(X_Dpy, XC_fleur);
Cursor_normal = XCreateFontCursor(X_Dpy, XC_left_ptr);
Cursor_question = XCreateFontCursor(X_Dpy, XC_question_arrow);
Cursor_resize = XCreateFontCursor(X_Dpy, XC_bottom_right_corner);
for (i = 0; i < ScreenCount(X_Dpy); i++) { for (i = 0; i < ScreenCount(X_Dpy); i++) {
sc = xcalloc(1, sizeof(*sc)); sc = xcalloc(1, sizeof(*sc));
x_setupscreen(sc, i); x_setupscreen(sc, i);
@@ -138,6 +129,12 @@ x_setup(void)
*/ */
TAILQ_FOREACH(kb, &Conf.keybindingq, entry) TAILQ_FOREACH(kb, &Conf.keybindingq, entry)
conf_grab(&Conf, kb); conf_grab(&Conf, kb);
Cursor_move = XCreateFontCursor(X_Dpy, XC_fleur);
Cursor_resize = XCreateFontCursor(X_Dpy, XC_bottom_right_corner);
Cursor_select = XCreateFontCursor(X_Dpy, XC_hand1);
Cursor_default = XCreateFontCursor(X_Dpy, XC_X_cursor);
Cursor_question = XCreateFontCursor(X_Dpy, XC_question_arrow);
} }
static void static void
@@ -169,6 +166,7 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
conf_color(&Conf, sc); conf_color(&Conf, sc);
group_init(sc); group_init(sc);
font_init(sc);
conf_font(&Conf, sc); conf_font(&Conf, sc);
TAILQ_INIT(&sc->mruq); TAILQ_INIT(&sc->mruq);
@@ -178,12 +176,11 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
xu_setwmname(sc); xu_setwmname(sc);
rootattr.cursor = Cursor_normal; rootattr.event_mask = ChildMask|PropertyChangeMask|EnterWindowMask|
rootattr.event_mask = CHILDMASK|PropertyChangeMask|EnterWindowMask| LeaveWindowMask|ColormapChangeMask|ButtonMask;
LeaveWindowMask|ColormapChangeMask|BUTTONMASK;
XChangeWindowAttributes(X_Dpy, sc->rootwin, XChangeWindowAttributes(X_Dpy, sc->rootwin,
CWEventMask|CWCursor, &rootattr); CWEventMask, &rootattr);
/* Deal with existing clients. */ /* Deal with existing clients. */
XQueryTree(X_Dpy, sc->rootwin, &w0, &w1, &wins, &nwins); XQueryTree(X_Dpy, sc->rootwin, &w0, &w1, &wins, &nwins);
@@ -193,7 +190,7 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
if (winattr.override_redirect || if (winattr.override_redirect ||
winattr.map_state != IsViewable) winattr.map_state != IsViewable)
continue; continue;
(void)client_new(wins[i], sc, winattr.map_state != IsUnmapped); client_new(wins[i], sc, winattr.map_state != IsUnmapped);
} }
XFree(wins); XFree(wins);
@@ -214,26 +211,28 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
XSync(X_Dpy, False); XSync(X_Dpy, False);
} }
static int
x_wmerrorhandler(Display *dpy, XErrorEvent *e)
{
errx(1, "root window unavailable - perhaps another wm is running?");
return (0);
}
static int static int
x_errorhandler(Display *dpy, XErrorEvent *e) x_errorhandler(Display *dpy, XErrorEvent *e)
{ {
#if DEBUG #ifdef DEBUG
char msg[80], number[80], req[80]; {
char msg[80], number[80], req[80];
XGetErrorText(X_Dpy, e->error_code, msg, sizeof(msg)); XGetErrorText(X_Dpy, e->error_code, msg, sizeof(msg));
(void)snprintf(number, sizeof(number), "%d", e->request_code); snprintf(number, sizeof(number), "%d", e->request_code);
XGetErrorDatabaseText(X_Dpy, "XRequest", number, XGetErrorDatabaseText(X_Dpy, "XRequest", number,
"<unknown>", req, sizeof(req)); "<unknown>", req, sizeof(req));
warnx("%s(0x%x): %s", req, (u_int)e->resourceid, msg); warnx("%s(0x%x): %s", req, (u_int)e->resourceid, msg);
}
#endif #endif
if (Starting &&
e->error_code == BadAccess &&
e->request_code == X_GrabKey)
errx(1, "root window unavailable - perhaps another "
"wm is running?");
return (0); return (0);
} }
@@ -257,7 +256,6 @@ usage(void)
{ {
extern char *__progname; extern char *__progname;
(void)fprintf(stderr, "usage: %s [-c file] [-d display]\n", fprintf(stderr, "usage: %s [-c file] [-d display]\n", __progname);
__progname);
exit(1); exit(1);
} }

700
calmwm.h
View File

@@ -15,23 +15,15 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $OpenBSD$ * $Id$
*/ */
#ifndef _CALMWM_H_ #ifndef _CALMWM_H_
#define _CALMWM_H_ #define _CALMWM_H_
/* ugly stuff */ /* ugly stuff */
#ifndef TAILQ_END
#define TAILQ_END(head) NULL #define TAILQ_END(head) NULL
#endif
#ifndef __dead
#define __dead #define __dead
#endif
char *fgetln(FILE *, size_t *);
long long strtonum(const char *, long long, long long, const char **);
size_t strlcpy(char *, const char *, size_t);
size_t strlcat(char *, const char *, size_t);
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <X11/Xft/Xft.h> #include <X11/Xft/Xft.h>
@@ -43,70 +35,40 @@ size_t strlcat(char *, const char *, size_t);
#include <X11/extensions/Xrandr.h> #include <X11/extensions/Xrandr.h>
#include <X11/keysym.h> #include <X11/keysym.h>
#define CALMWM_MAXNAMELEN 256
#undef MIN #undef MIN
#undef MAX #undef MAX
#define MIN(x, y) ((x) < (y) ? (x) : (y)) #define MIN(x, y) ((x) < (y) ? (x) : (y))
#define MAX(x, y) ((x) > (y) ? (x) : (y)) #define MAX(x, y) ((x) > (y) ? (x) : (y))
#ifndef nitems
#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
#endif
#define CONFFILE ".cwmrc" #define CONFFILE ".cwmrc"
#define WMNAME "CWM" #define WMNAME "CWM"
#define CHILDMASK (SubstructureRedirectMask|SubstructureNotifyMask) #define ChildMask (SubstructureRedirectMask|SubstructureNotifyMask)
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) #define ButtonMask (ButtonPressMask|ButtonReleaseMask)
#define MOUSEMASK (BUTTONMASK|PointerMotionMask) #define MouseMask (ButtonMask|PointerMotionMask)
#define KEYMASK (KeyPressMask|ExposureMask) #define KeyMask (KeyPressMask|ExposureMask)
#define MENUMASK (BUTTONMASK|ButtonMotionMask|ExposureMask| \ #define MenuMask (ButtonMask|ButtonMotionMask|ExposureMask| \
PointerMotionMask) PointerMotionMask)
#define MENUGRABMASK (BUTTONMASK|ButtonMotionMask|StructureNotifyMask|\ #define MenuGrabMask (ButtonMask|ButtonMotionMask|StructureNotifyMask|\
PointerMotionMask) PointerMotionMask)
#define SEARCHMASK (KeyPressMask|ExposureMask) #define SearchMask (KeyPressMask|ExposureMask)
/* kb movement */
#define CWM_MOVE 0x0001
#define CWM_RESIZE 0x0002
#define CWM_PTRMOVE 0x0004
#define CWM_BIGMOVE 0x0008
#define CWM_UP 0x0010
#define CWM_DOWN 0x0020
#define CWM_LEFT 0x0040
#define CWM_RIGHT 0x0080
/* exec */
#define CWM_EXEC_PROGRAM 0x0001
#define CWM_EXEC_WM 0x0002
/* cycle */
#define CWM_CYCLE 0x0001
#define CWM_RCYCLE 0x0002
#define CWM_INGROUP 0x0004
#define KBTOGROUP(X) ((X) - 1)
union arg {
char *c;
int i;
};
enum cwmcolor { enum cwmcolor {
CWM_COLOR_BORDER_ACTIVE, CWM_COLOR_BORDOR_ACTIVE,
CWM_COLOR_BORDER_INACTIVE, CWM_COLOR_BORDER_INACTIVE,
CWM_COLOR_BORDER_GROUP, CWM_COLOR_BORDER_GROUP,
CWM_COLOR_BORDER_UNGROUP, CWM_COLOR_BORDER_UNGROUP,
CWM_COLOR_FG_MENU, CWM_COLOR_FG_MENU,
CWM_COLOR_BG_MENU, CWM_COLOR_BG_MENU,
CWM_COLOR_FONT,
CWM_COLOR_MAX CWM_COLOR_MAX
}; };
struct color { struct color {
char *name;
unsigned long pixel; unsigned long pixel;
char *name;
}; };
struct gap { struct gap {
int top; int top;
int bottom; int bottom;
@@ -114,81 +76,13 @@ struct gap {
int right; int right;
}; };
struct winname { struct client_ctx;
TAILQ_ENTRY(winname) entry;
char *name;
};
TAILQ_HEAD(winname_q, winname);
struct client_ctx {
TAILQ_ENTRY(client_ctx) entry;
TAILQ_ENTRY(client_ctx) group_entry;
TAILQ_ENTRY(client_ctx) mru_entry;
struct screen_ctx *sc;
Window win;
XSizeHints *size;
Colormap cmap;
u_int bwidth; /* border width */
struct {
int x; /* x position */
int y; /* y position */
int width; /* width */
int height;/* height */
} geom, savegeom;
struct {
int basew; /* desired width */
int baseh; /* desired height */
int minw; /* minimum width */
int minh; /* minimum height */
int maxw; /* maximum width */
int maxh; /* maximum height */
int incw; /* width increment progression */
int inch; /* height increment progression */
float mina; /* minimum aspect ratio */
float maxa; /* maximum aspect ratio */
} hint;
struct {
int x; /* x position */
int y; /* y position */
} ptr;
#define CLIENT_PROTO_DELETE 0x0001
#define CLIENT_PROTO_TAKEFOCUS 0x0002
int xproto;
#define CLIENT_HIDDEN 0x0001
#define CLIENT_IGNORE 0x0002
#define CLIENT_VMAXIMIZED 0x0004
#define CLIENT_HMAXIMIZED 0x0008
#define CLIENT_FREEZE 0x0010
#define CLIENT_MAXFLAGS (CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED)
#define CLIENT_MAXIMIZED (CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED)
int flags;
int state;
int active;
int stackingorder;
#define CLIENT_HIGHLIGHT_GROUP 0x0001
#define CLIENT_HIGHLIGHT_UNGROUP 0x0002
int highlight;
struct winname_q nameq;
#define CLIENT_MAXNAMEQLEN 5
int nameqlen;
char *name;
char *label;
char *matchname;
struct group_ctx *group;
char *app_class;
char *app_name;
};
TAILQ_HEAD(client_ctx_q, client_ctx);
TAILQ_HEAD(cycle_entry_q, client_ctx); TAILQ_HEAD(cycle_entry_q, client_ctx);
TAILQ_HEAD(group_ctx_q, group_ctx);
TAILQ_HEAD(client_ctx_q, client_ctx);
struct winmatch { #define CALMWM_NGROUPS 9
TAILQ_ENTRY(winmatch) entry;
#define WIN_MAXTITLELEN 256
char title[WIN_MAXTITLELEN];
};
TAILQ_HEAD(winmatch_q, winmatch);
struct group_ctx { struct group_ctx {
TAILQ_ENTRY(group_ctx) entry; TAILQ_ENTRY(group_ctx) entry;
struct client_ctx_q clients; struct client_ctx_q clients;
@@ -197,42 +91,161 @@ struct group_ctx {
int nhidden; int nhidden;
int highstack; int highstack;
}; };
TAILQ_HEAD(group_ctx_q, group_ctx);
struct screen_ctx {
TAILQ_ENTRY(screen_ctx) entry;
u_int which;
Window rootwin;
Window menuwin;
struct color color[CWM_COLOR_MAX];
GC gc;
int altpersist;
int xmax;
int ymax;
struct gap gap;
struct cycle_entry_q mruq;
XftDraw *xftdraw;
XftColor xftcolor;
XftFont *font;
u_int fontheight;
int xinerama_no;
XineramaScreenInfo *xinerama;
struct group_ctx *group_active;
struct group_ctx groups[CALMWM_NGROUPS];
int group_hideall;
struct group_ctx_q groupq;
char **group_names;
int group_nonames;
};
TAILQ_HEAD(screen_ctx_q, screen_ctx);
#define CLIENT_PROTO_DELETE 0x01
#define CLIENT_PROTO_TAKEFOCUS 0x02
#define CLIENT_MAXNAMEQLEN 5
#define CLIENT_HIDDEN 0x01
#define CLIENT_IGNORE 0x02
#define CLIENT_DOMAXIMIZE 0x04
#define CLIENT_MAXIMIZED 0x08
#define CLIENT_DOVMAXIMIZE 0x10
#define CLIENT_VMAXIMIZED 0x20
#define CLIENT_DOHMAXIMIZE 0x40
#define CLIENT_HMAXIMIZED 0x80
#define CLIENT_HIGHLIGHT_GROUP 1
#define CLIENT_HIGHLIGHT_UNGROUP 2
struct winname {
TAILQ_ENTRY(winname) entry;
char *name;
};
TAILQ_HEAD(winname_q, winname);
struct client_ctx {
TAILQ_ENTRY(client_ctx) entry;
TAILQ_ENTRY(client_ctx) searchentry;
TAILQ_ENTRY(client_ctx) group_entry;
TAILQ_ENTRY(client_ctx) mru_entry;
struct screen_ctx *sc;
Window win;
XSizeHints *size;
Colormap cmap;
u_int bwidth;
struct {
int x, y, width, height, basew, baseh,
minw, minh, maxw, maxh, incw, inch;
float mina, maxa;
} geom, savegeom;
struct {
int x,y;
} ptr;
int xproto;
int flags;
int state;
char *name;
struct winname_q nameq;
size_t nameqlen;
char *label;
int active;
int highlight;
char *matchname;
struct group_ctx *group;
int stackingorder;
char *app_class;
char *app_name;
char *app_cliarg;
};
extern const char *shortcut_to_name[];
/* Autogroups */
struct autogroupwin { struct autogroupwin {
TAILQ_ENTRY(autogroupwin) entry; TAILQ_ENTRY(autogroupwin) entry;
char *class; char *class;
char *name; char *name;
int num; int num;
}; };
TAILQ_HEAD(autogroupwin_q, autogroupwin); TAILQ_HEAD(autogroupwin_q, autogroupwin);
struct screen_ctx { #define CWM_MOVE 0x01
TAILQ_ENTRY(screen_ctx) entry; #define CWM_RESIZE 0x02
u_int which; #define CWM_PTRMOVE 0x04
Window rootwin; #define CWM_BIGMOVE 0x08
Window menuwin; #define CWM_UP 0x10
struct color color[CWM_COLOR_MAX]; #define CWM_DOWN 0x20
GC gc; #define CWM_LEFT 0x40
int altpersist; #define CWM_RIGHT 0x80
int xmax;
int ymax; /*
struct gap gap; * Match a window.
struct cycle_entry_q mruq; */
XftColor xftcolor; #define CONF_MAX_WINTITLE 256
XftDraw *xftdraw; struct winmatch {
XftFont *font; TAILQ_ENTRY(winmatch) entry;
int xinerama_no; char title[CONF_MAX_WINTITLE];
XineramaScreenInfo *xinerama; };
#define CALMWM_NGROUPS 9
struct group_ctx groups[CALMWM_NGROUPS]; TAILQ_HEAD(winmatch_q, winmatch);
struct group_ctx_q groupq;
int group_hideall; /* for cwm_exec */
int group_nonames; #define CWM_EXEC_PROGRAM 0x1
struct group_ctx *group_active; #define CWM_EXEC_WM 0x2
char **group_names; /* for alt-tab */
#define CWM_CYCLE 0x0
#define CWM_RCYCLE 0x1
/* for group cycle */
#define CWM_CYCLEGROUP 0x0
#define CWM_RCYCLEGROUP 0x1
#define KBFLAG_NEEDCLIENT 0x01
#define KBTOGROUP(X) ((X) - 1)
union arg {
char *c;
int i;
}; };
TAILQ_HEAD(screen_ctx_q, screen_ctx);
struct keybinding { struct keybinding {
TAILQ_ENTRY(keybinding) entry; TAILQ_ENTRY(keybinding) entry;
@@ -241,43 +254,33 @@ struct keybinding {
int modmask; int modmask;
int keysym; int keysym;
int keycode; int keycode;
#define KBFLAG_NEEDCLIENT 0x0001
int flags; int flags;
}; };
TAILQ_HEAD(keybinding_q, keybinding);
struct mousebinding {
TAILQ_ENTRY(mousebinding) entry;
void (*callback)(struct client_ctx *, void *);
int modmask;
int button;
#define MOUSEBIND_CTX_ROOT 0x0001
#define MOUSEBIND_CTX_WIN 0x0002
int context;
};
TAILQ_HEAD(mousebinding_q, mousebinding);
struct cmd { struct cmd {
TAILQ_ENTRY(cmd) entry; TAILQ_ENTRY(cmd) entry;
int flags; int flags;
char image[MAXPATHLEN]; char image[MAXPATHLEN];
#define CMD_MAXLABELLEN 256 char label[256];
char label[CMD_MAXLABELLEN]; /* (argv) */
}; };
struct mousebinding {
int modmask;
int button;
int context;
void (*callback)(struct client_ctx *, void *);
TAILQ_ENTRY(mousebinding) entry;
};
#define MOUSEBIND_CTX_ROOT 1
#define MOUSEBIND_CTX_WIN 2
TAILQ_HEAD(keybinding_q, keybinding);
TAILQ_HEAD(cmd_q, cmd); TAILQ_HEAD(cmd_q, cmd);
TAILQ_HEAD(mousebinding_q, mousebinding);
struct menu { /* Global configuration */
TAILQ_ENTRY(menu) entry;
TAILQ_ENTRY(menu) resultentry;
#define MENU_MAXENTRY 50
char text[MENU_MAXENTRY + 1];
char print[MENU_MAXENTRY + 1];
void *ctx;
short dummy;
short abort;
};
TAILQ_HEAD(menu_q, menu);
struct conf { struct conf {
struct keybinding_q keybindingq; struct keybinding_q keybindingq;
struct autogroupwin_q autogroupq; struct autogroupwin_q autogroupq;
@@ -285,141 +288,99 @@ struct conf {
char conf_path[MAXPATHLEN]; char conf_path[MAXPATHLEN];
struct cmd_q cmdq; struct cmd_q cmdq;
struct mousebinding_q mousebindingq; struct mousebinding_q mousebindingq;
#define CONF_STICKY_GROUPS 0x0001
#define CONF_STICKY_GROUPS 0x0001
int flags; int flags;
#define CONF_BWIDTH 1 #define CONF_BWIDTH 1
int bwidth; int bwidth;
#define CONF_MAMOUNT 1 #define CONF_MAMOUNT 1
int mamount; int mamount;
#define CONF_SNAPDIST 0
int snapdist;
struct gap gap; struct gap gap;
#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]; struct color color[CWM_COLOR_MAX];
char termpath[MAXPATHLEN]; char termpath[MAXPATHLEN];
char lockpath[MAXPATHLEN]; char lockpath[MAXPATHLEN];
#define CONF_FONT "sans-serif:pixelsize=14:bold"
char *font; #define DEFAULTFONTNAME "sans-serif:pixelsize=14:bold"
char *DefaultFontName;
};
/* Menu stuff */
#define MENU_MAXENTRY 50
struct menu {
TAILQ_ENTRY(menu) entry;
TAILQ_ENTRY(menu) resultentry;
char text[MENU_MAXENTRY + 1];
char print[MENU_MAXENTRY + 1];
void *ctx;
short dummy;
short abort;
};
TAILQ_HEAD(menu_q, menu);
enum ctltype {
CTL_NONE = -1,
CTL_ERASEONE = 0, CTL_WIPE, CTL_UP, CTL_DOWN, CTL_RETURN,
CTL_ABORT, CTL_ALL
}; };
/* MWM hints */ /* MWM hints */
struct mwm_hints { struct mwm_hints {
u_long flags; u_long flags;
u_long functions; u_long functions;
u_long decorations; u_long decorations;
}; };
#define MWM_NUMHINTS 3
#define MWM_NUMHINTS 3
#define PROP_MWM_HINTS_ELEMENTS 3 #define PROP_MWM_HINTS_ELEMENTS 3
#define MWM_HINTS_DECORATIONS (1<<1) #define MWM_HINTS_DECORATIONS (1 << 1)
#define MWM_DECOR_ALL (1<<0) #define MWM_DECOR_ALL (1 << 0)
#define MWM_DECOR_BORDER (1<<1) #define MWM_DECOR_BORDER (1 << 1)
int input_keycodetrans(KeyCode, u_int, enum ctltype *,
char *);
__dead void usage(void); __dead void usage(void);
void client_applysizehints(struct client_ctx *);
struct client_ctx *client_current(void);
void client_cycle(struct screen_ctx *, int);
void client_delete(struct client_ctx *);
void client_draw_border(struct client_ctx *);
struct client_ctx *client_find(Window); struct client_ctx *client_find(Window);
void client_freeze(struct client_ctx *);
void client_getsizehints(struct client_ctx *);
void client_hide(struct client_ctx *);
void client_horizmaximize(struct client_ctx *);
void client_leave(struct client_ctx *);
void client_lower(struct client_ctx *);
void client_map(struct client_ctx *);
void client_maximize(struct client_ctx *);
void client_move(struct client_ctx *);
void client_mtf(struct client_ctx *);
struct client_ctx *client_new(Window, struct screen_ctx *, int); struct client_ctx *client_new(Window, struct screen_ctx *, int);
void client_ptrsave(struct client_ctx *); int client_delete(struct client_ctx *);
void client_ptrwarp(struct client_ctx *);
void client_raise(struct client_ctx *);
void client_resize(struct client_ctx *);
void client_send_delete(struct client_ctx *);
void client_setactive(struct client_ctx *, int); void client_setactive(struct client_ctx *, int);
void client_setname(struct client_ctx *); void client_resize(struct client_ctx *);
int client_snapcalc(int, int, int, int, int); void client_lower(struct client_ctx *);
void client_transient(struct client_ctx *); void client_raise(struct client_ctx *);
void client_move(struct client_ctx *);
void client_leave(struct client_ctx *);
void client_send_delete(struct client_ctx *);
struct client_ctx *client_current(void);
void client_hide(struct client_ctx *);
void client_unhide(struct client_ctx *); void client_unhide(struct client_ctx *);
void client_vertmaximize(struct client_ctx *); void client_setname(struct client_ctx *);
void client_warp(struct client_ctx *); void client_warp(struct client_ctx *);
void client_ptrwarp(struct client_ctx *);
void group_alltoggle(struct screen_ctx *); void client_ptrsave(struct client_ctx *);
void group_autogroup(struct client_ctx *); void client_draw_border(struct client_ctx *);
void group_client_delete(struct client_ctx *); void client_maximize(struct client_ctx *);
void group_cycle(struct screen_ctx *, int); void client_vertmaximize(struct client_ctx *);
void group_hidetoggle(struct screen_ctx *, int); void client_horizmaximize(struct client_ctx *);
void group_init(struct screen_ctx *); void client_map(struct client_ctx *);
void group_make_autogroup(struct conf *, char *, int); void client_mtf(struct client_ctx *);
void group_menu(XButtonEvent *); struct client_ctx *client_cycle(struct screen_ctx *, int);
void group_movetogroup(struct client_ctx *, int); void client_getsizehints(struct client_ctx *);
void group_only(struct screen_ctx *, int); void client_applysizehints(struct client_ctx *);
void group_sticky(struct client_ctx *);
void group_sticky_toggle_enter(struct client_ctx *);
void group_sticky_toggle_exit(struct client_ctx *);
void group_update_names(struct screen_ctx *);
void search_match_client(struct menu_q *, struct menu_q *,
char *);
void search_match_exec(struct menu_q *, struct menu_q *,
char *);
void search_match_text(struct menu_q *, struct menu_q *,
char *);
void search_print_client(struct menu *, int);
XineramaScreenInfo *screen_find_xinerama(struct screen_ctx *, int, int);
struct screen_ctx *screen_fromroot(Window);
void screen_init_xinerama(struct screen_ctx *);
void screen_update_geometry(struct screen_ctx *, int, int);
void screen_updatestackingorder(struct screen_ctx *);
void kbfunc_client_cycle(struct client_ctx *, union arg *);
void kbfunc_client_cyclegroup(struct client_ctx *,
union arg *);
void kbfunc_client_delete(struct client_ctx *, union arg *);
void kbfunc_client_freeze(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_grouptoggle(struct client_ctx *,
union arg *);
void kbfunc_client_hide(struct client_ctx *, union arg *);
void kbfunc_client_hmaximize(struct client_ctx *,
union arg *);
void kbfunc_client_label(struct client_ctx *, union arg *);
void kbfunc_client_lower(struct client_ctx *, union arg *);
void kbfunc_client_maximize(struct client_ctx *,
union arg *);
void kbfunc_client_movetogroup(struct client_ctx *,
union arg *);
void kbfunc_client_nogroup(struct client_ctx *,
union arg *);
void kbfunc_client_raise(struct client_ctx *, union arg *);
void kbfunc_client_rcycle(struct client_ctx *, union arg *);
void kbfunc_client_search(struct client_ctx *, union arg *);
void kbfunc_client_vmaximize(struct client_ctx *,
union arg *);
void kbfunc_cmdexec(struct client_ctx *, union arg *);
void kbfunc_exec(struct client_ctx *, union arg *);
void kbfunc_lock(struct client_ctx *, union arg *);
void kbfunc_menu_search(struct client_ctx *, union arg *);
void kbfunc_moveresize(struct client_ctx *, union arg *);
void kbfunc_quit_wm(struct client_ctx *, union arg *);
void kbfunc_reload(struct client_ctx *, union arg *);
void kbfunc_ssh(struct client_ctx *, union arg *);
void kbfunc_term(struct client_ctx *, union arg *);
void mousefunc_menu_cmd(struct client_ctx *, void *);
void mousefunc_menu_group(struct client_ctx *, void *);
void mousefunc_menu_unhide(struct client_ctx *, void *);
void mousefunc_window_grouptoggle(struct client_ctx *,
void *);
void mousefunc_window_hide(struct client_ctx *, void *);
void mousefunc_window_lower(struct client_ctx *, void *);
void mousefunc_window_move(struct client_ctx *, void *);
void mousefunc_window_raise(struct client_ctx *, void *);
void mousefunc_window_resize(struct client_ctx *, void *);
struct menu *menu_filter(struct screen_ctx *, struct menu_q *, struct menu *menu_filter(struct screen_ctx *, struct menu_q *,
char *, char *, int, char *, char *, int,
@@ -427,76 +388,155 @@ struct menu *menu_filter(struct screen_ctx *, struct menu_q *,
void (*)(struct menu *, int)); void (*)(struct menu *, int));
void menu_init(struct screen_ctx *); void menu_init(struct screen_ctx *);
int parse_config(const char *, struct conf *); /* XXX should be xu_ */
void xev_reconfig(struct client_ctx *);
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 *, int);
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_init(struct conf *);
void conf_mousebind(struct conf *, char *, char *);
void conf_reload(struct conf *);
void conf_setup(struct conf *, const 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);
u_int font_height(struct screen_ctx *);
void font_init(struct screen_ctx *, const char *);
int font_width(struct screen_ctx *, const char *, int);
XftFont *font_make(struct screen_ctx *, const char *);
void xev_loop(void); void xev_loop(void);
void xu_btn_grab(Window, int, u_int);
void xu_btn_ungrab(Window, int, u_int);
void xu_configure(struct client_ctx *);
void xu_freecolor(struct screen_ctx *, unsigned long);
void xu_getatoms(void); void xu_getatoms(void);
unsigned long xu_getcolor(struct screen_ctx *, char *); int xu_ptr_grab(Window, int, Cursor);
int xu_getprop(Window, Atom, Atom, long, u_char **); void xu_btn_grab(Window, int, u_int);
int xu_getstate(struct client_ctx *, int *); int xu_ptr_regrab(int, Cursor);
int xu_getstrprop(Window, Atom, char **); void xu_btn_ungrab(Window, int, u_int);
void xu_ptr_ungrab(void);
void xu_ptr_setpos(Window, int, int);
void xu_ptr_getpos(Window, int *, int *);
void xu_key_grab(Window, int, int); void xu_key_grab(Window, int, int);
void xu_key_ungrab(Window, int, int); void xu_key_ungrab(Window, int, int);
void xu_ptr_getpos(Window, int *, int *);
int xu_ptr_grab(Window, int, Cursor);
int xu_ptr_regrab(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, long);
int xu_getprop(Window, Atom, Atom, long, u_char **);
int xu_getstrprop(Window, Atom, char **);
void xu_setstate(struct client_ctx *, int); 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);
void xu_setwmname(struct screen_ctx *); void xu_setwmname(struct screen_ctx *);
int u_spawn(char *);
void u_exec(char *); void u_exec(char *);
void u_spawn(char *);
void *xcalloc(size_t, size_t);
void xfree(void *); void xfree(void *);
void *xmalloc(size_t); void *xmalloc(size_t);
void *xcalloc(size_t, size_t);
char *xstrdup(const char *); char *xstrdup(const char *);
struct screen_ctx *screen_fromroot(Window);
void screen_updatestackingorder(struct screen_ctx *);
void screen_update_geometry(struct screen_ctx *, int, int);
void screen_init_xinerama(struct screen_ctx *);
XineramaScreenInfo *screen_find_xinerama(struct screen_ctx *, int, int);
void conf_setup(struct conf *, const char *);
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_mousebind(struct conf *, char *, char *);
void conf_grab_mouse(struct client_ctx *);
void conf_reload(struct conf *);
void conf_gap(struct conf *, struct screen_ctx *);
void conf_font(struct conf *, struct screen_ctx *);
void conf_color(struct conf *, struct screen_ctx *);
void conf_init(struct conf *);
void conf_clear(struct conf *);
void conf_cmd_add(struct conf *, char *, char *, int);
int parse_config(const char *, struct conf *);
void kbfunc_client_lower(struct client_ctx *, union arg *);
void kbfunc_client_raise(struct client_ctx *, union arg *);
void kbfunc_client_search(struct client_ctx *, union arg *);
void kbfunc_client_hide(struct client_ctx *, union arg *);
void kbfunc_client_cycle(struct client_ctx *, union arg *);
void kbfunc_client_rcycle(struct client_ctx *, union arg *);
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 *,
union arg *);
void kbfunc_client_hmaximize(struct client_ctx *,
union arg *);
void kbfunc_reload(struct client_ctx *, union arg *);
void kbfunc_quit_wm(struct client_ctx *, union arg *);
void kbfunc_moveresize(struct client_ctx *, union arg *);
void kbfunc_menu_search(struct client_ctx *, union arg *);
void kbfunc_exec(struct client_ctx *, union arg *);
void kbfunc_ssh(struct client_ctx *, union arg *);
void kbfunc_term(struct client_ctx *, union arg *);
void kbfunc_lock(struct client_ctx *, union arg *);
void mousefunc_window_resize(struct client_ctx *, void *);
void mousefunc_window_move(struct client_ctx *, void *);
void mousefunc_window_grouptoggle(struct client_ctx *,
void *);
void mousefunc_window_lower(struct client_ctx *, void *);
void mousefunc_window_hide(struct client_ctx *, void *);
void mousefunc_menu_group(struct client_ctx *, void *);
void mousefunc_menu_unhide(struct client_ctx *, void *);
void mousefunc_menu_cmd(struct client_ctx *, void *);
void search_match_client(struct menu_q *, struct menu_q *,
char *);
void search_print_client(struct menu *, int);
void search_match_text(struct menu_q *, struct menu_q *,
char *);
void search_match_exec(struct menu_q *, struct menu_q *,
char *);
void group_init(struct screen_ctx *);
void group_make_autogroup(struct conf *, char *, int);
void group_update_names(struct screen_ctx *);
void group_hidetoggle(struct screen_ctx *, int);
void group_only(struct screen_ctx *, int);
void group_cycle(struct screen_ctx *, int);
void group_sticky(struct client_ctx *);
void group_client_delete(struct client_ctx *);
void group_menu(XButtonEvent *);
void group_alltoggle(struct screen_ctx *);
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);
int font_ascent(struct screen_ctx *);
int font_descent(struct screen_ctx *);
u_int font_height(struct screen_ctx *);
void font_init(struct screen_ctx *);
int font_width(struct screen_ctx *, const char *, int);
void font_draw(struct screen_ctx *, const char *, int,
Drawable, int, int);
XftFont *font_make(struct screen_ctx *, const char *);
/* Externs */ /* Externs */
extern Display *X_Dpy; extern Display *X_Dpy;
extern Cursor Cursor_default;
extern Cursor Cursor_move; extern Cursor Cursor_move;
extern Cursor Cursor_normal;
extern Cursor Cursor_question;
extern Cursor Cursor_resize; extern Cursor Cursor_resize;
extern Cursor Cursor_select;
extern Cursor Cursor_default;
extern Cursor Cursor_question;
extern struct screen_ctx_q Screenq; extern struct screen_ctx_q Screenq;
extern struct screen_ctx *curscreen;
extern struct client_ctx_q Clientq; extern struct client_ctx_q Clientq;
extern struct conf Conf;
extern int HasXinerama, HasRandr, Randr_ev; extern int HasXinerama, HasRandr, Randr_ev;
extern struct conf Conf;
#define WM_STATE cwm_atoms[0] #define WM_STATE cwm_atoms[0]
#define WM_DELETE_WINDOW cwm_atoms[1] #define WM_DELETE_WINDOW cwm_atoms[1]

393
client.c
View File

@@ -15,7 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $OpenBSD$ * $Id$
*/ */
#include <sys/param.h> #include <sys/param.h>
@@ -113,10 +113,8 @@ client_new(Window win, struct screen_ctx *sc, int mapped)
XAddToSaveSet(X_Dpy, cc->win); XAddToSaveSet(X_Dpy, cc->win);
client_transient(cc);
/* Notify client of its configuration. */ /* Notify client of its configuration. */
xu_configure(cc); xev_reconfig(cc);
(state == IconicState) ? client_hide(cc) : client_unhide(cc); (state == IconicState) ? client_hide(cc) : client_unhide(cc);
xu_setstate(cc, cc->state); xu_setstate(cc, cc->state);
@@ -139,7 +137,7 @@ client_new(Window win, struct screen_ctx *sc, int mapped)
return (cc); return (cc);
} }
void int
client_delete(struct client_ctx *cc) client_delete(struct client_ctx *cc)
{ {
struct screen_ctx *sc = cc->sc; struct screen_ctx *sc = cc->sc;
@@ -191,6 +189,8 @@ client_delete(struct client_ctx *cc)
client_freehints(cc); client_freehints(cc);
xfree(cc); xfree(cc);
return (0);
} }
void void
@@ -264,15 +264,6 @@ client_current(void)
return (_curcc); return (_curcc);
} }
void
client_freeze(struct client_ctx *cc)
{
if (cc->flags & CLIENT_FREEZE)
cc->flags &= ~CLIENT_FREEZE;
else
cc->flags |= CLIENT_FREEZE;
}
void void
client_maximize(struct client_ctx *cc) client_maximize(struct client_ctx *cc)
{ {
@@ -280,52 +271,36 @@ client_maximize(struct client_ctx *cc)
int xmax = sc->xmax, ymax = sc->ymax; int xmax = sc->xmax, ymax = sc->ymax;
int x_org = 0, y_org = 0; int x_org = 0, y_org = 0;
if (cc->flags & CLIENT_FREEZE) if (cc->flags & CLIENT_MAXIMIZED) {
return;
if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_MAXIMIZED) {
cc->flags &= ~CLIENT_MAXIMIZED;
cc->geom = cc->savegeom; cc->geom = cc->savegeom;
cc->bwidth = Conf.bwidth; } else {
goto resize; if (!(cc->flags & (CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED)))
} cc->savegeom = cc->geom;
if (HasXinerama) {
if ((cc->flags & CLIENT_VMAXIMIZED) == 0) { XineramaScreenInfo *xine;
cc->savegeom.height = cc->geom.height; /*
cc->savegeom.y = cc->geom.y; * pick screen that the middle of the window is on.
} * that's probably more fair than if just the origin of
* a window is poking over a boundary
if ((cc->flags & CLIENT_HMAXIMIZED) == 0) { */
cc->savegeom.width = cc->geom.width; xine = screen_find_xinerama(sc,
cc->savegeom.x = cc->geom.x; cc->geom.x + cc->geom.width / 2,
} cc->geom.y + cc->geom.height / 2);
if (xine == NULL)
if (HasXinerama) { goto calc;
XineramaScreenInfo *xine; x_org = xine->x_org;
/* y_org = xine->y_org;
* pick screen that the middle of the window is on. xmax = xine->width;
* that's probably more fair than if just the origin of ymax = xine->height;
* a window is poking over a boundary }
*/
xine = screen_find_xinerama(sc,
cc->geom.x + cc->geom.width / 2,
cc->geom.y + cc->geom.height / 2);
if (xine == NULL)
goto calc;
x_org = xine->x_org;
y_org = xine->y_org;
xmax = xine->width;
ymax = xine->height;
}
calc: calc:
cc->geom.x = x_org + sc->gap.left; cc->geom.x = x_org + sc->gap.left;
cc->geom.y = y_org + sc->gap.top; cc->geom.y = y_org + sc->gap.top;
cc->geom.height = ymax - (sc->gap.top + sc->gap.bottom); cc->geom.height = ymax - (sc->gap.top + sc->gap.bottom);
cc->geom.width = xmax - (sc->gap.left + sc->gap.right); cc->geom.width = xmax - (sc->gap.left + sc->gap.right);
cc->bwidth = 0; cc->flags |= CLIENT_DOMAXIMIZE;
cc->flags |= CLIENT_MAXIMIZED; }
resize:
client_resize(cc); client_resize(cc);
} }
@@ -335,45 +310,28 @@ client_vertmaximize(struct client_ctx *cc)
struct screen_ctx *sc = cc->sc; struct screen_ctx *sc = cc->sc;
int y_org = 0, ymax = sc->ymax; int y_org = 0, ymax = sc->ymax;
if (cc->flags & CLIENT_FREEZE)
return;
if (cc->flags & CLIENT_VMAXIMIZED) { if (cc->flags & CLIENT_VMAXIMIZED) {
cc->geom.y = cc->savegeom.y; cc->geom = cc->savegeom;
cc->geom.height = cc->savegeom.height; } else {
cc->bwidth = Conf.bwidth; if (!(cc->flags & (CLIENT_MAXIMIZED | CLIENT_HMAXIMIZED)))
if (cc->flags & CLIENT_HMAXIMIZED) cc->savegeom = cc->geom;
cc->geom.width -= cc->bwidth * 2; if (HasXinerama) {
cc->flags &= ~CLIENT_VMAXIMIZED; XineramaScreenInfo *xine;
goto resize; xine = screen_find_xinerama(sc,
} cc->geom.x + cc->geom.width / 2,
cc->geom.y + cc->geom.height / 2);
cc->savegeom.y = cc->geom.y; if (xine == NULL)
cc->savegeom.height = cc->geom.height; goto calc;
y_org = xine->y_org;
/* if this will make us fully maximized then remove boundary */ ymax = xine->height;
if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_HMAXIMIZED) { }
cc->geom.width += Conf.bwidth * 2;
cc->bwidth = 0;
}
if (HasXinerama) {
XineramaScreenInfo *xine;
xine = screen_find_xinerama(sc,
cc->geom.x + cc->geom.width / 2,
cc->geom.y + cc->geom.height / 2);
if (xine == NULL)
goto calc;
y_org = xine->y_org;
ymax = xine->height;
}
calc: calc:
cc->geom.y = y_org + sc->gap.top; cc->geom.y = y_org + sc->gap.top;
cc->geom.height = ymax - (cc->bwidth * 2) - (sc->gap.top + cc->geom.height = ymax - (cc->bwidth * 2) - (sc->gap.top +
sc->gap.bottom); sc->gap.bottom);
cc->flags |= CLIENT_VMAXIMIZED; cc->flags |= CLIENT_DOVMAXIMIZE;
}
resize:
client_resize(cc); client_resize(cc);
} }
@@ -383,63 +341,63 @@ client_horizmaximize(struct client_ctx *cc)
struct screen_ctx *sc = cc->sc; struct screen_ctx *sc = cc->sc;
int x_org = 0, xmax = sc->xmax; int x_org = 0, xmax = sc->xmax;
if (cc->flags & CLIENT_FREEZE)
return;
if (cc->flags & CLIENT_HMAXIMIZED) { if (cc->flags & CLIENT_HMAXIMIZED) {
cc->geom.x = cc->savegeom.x; cc->geom = cc->savegeom;
cc->geom.width = cc->savegeom.width; } else {
cc->bwidth = Conf.bwidth; if (!(cc->flags & (CLIENT_MAXIMIZED | CLIENT_VMAXIMIZED)))
if (cc->flags & CLIENT_VMAXIMIZED) cc->savegeom = cc->geom;
cc->geom.height -= cc->bwidth * 2; if (HasXinerama) {
cc->flags &= ~CLIENT_HMAXIMIZED; XineramaScreenInfo *xine;
goto resize; xine = screen_find_xinerama(sc,
} cc->geom.x + cc->geom.width / 2,
cc->geom.y + cc->geom.height / 2);
cc->savegeom.x = cc->geom.x; if (xine == NULL)
cc->savegeom.width = cc->geom.width; goto calc;
x_org = xine->x_org;
/* if this will make us fully maximized then remove boundary */ xmax = xine->width;
if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_VMAXIMIZED) { }
cc->geom.height += cc->bwidth * 2;
cc->bwidth = 0;
}
if (HasXinerama) {
XineramaScreenInfo *xine;
xine = screen_find_xinerama(sc,
cc->geom.x + cc->geom.width / 2,
cc->geom.y + cc->geom.height / 2);
if (xine == NULL)
goto calc;
x_org = xine->x_org;
xmax = xine->width;
}
calc: calc:
cc->geom.x = x_org + sc->gap.left; cc->geom.x = x_org + sc->gap.left;
cc->geom.width = xmax - (cc->bwidth * 2) - (sc->gap.left + cc->geom.width = xmax - (cc->bwidth * 2) - (sc->gap.left +
sc->gap.right); sc->gap.right);
cc->flags |= CLIENT_HMAXIMIZED; cc->flags |= CLIENT_DOHMAXIMIZE;
}
resize:
client_resize(cc); client_resize(cc);
} }
void void
client_resize(struct client_ctx *cc) client_resize(struct client_ctx *cc)
{ {
cc->flags &= ~(CLIENT_MAXIMIZED | CLIENT_VMAXIMIZED |
CLIENT_HMAXIMIZED);
if (cc->flags & CLIENT_DOMAXIMIZE) {
cc->bwidth = 0;
cc->flags &= ~CLIENT_DOMAXIMIZE;
cc->flags |= CLIENT_MAXIMIZED;
} else if (cc->flags & CLIENT_DOVMAXIMIZE) {
cc->flags &= ~CLIENT_DOVMAXIMIZE;
cc->flags |= CLIENT_VMAXIMIZED;
} else if (cc->flags & CLIENT_DOHMAXIMIZE) {
cc->flags &= ~CLIENT_DOHMAXIMIZE;
cc->flags |= CLIENT_HMAXIMIZED;
} else {
cc->bwidth = Conf.bwidth;
}
client_draw_border(cc); client_draw_border(cc);
XMoveResizeWindow(X_Dpy, cc->win, cc->geom.x, XMoveResizeWindow(X_Dpy, cc->win, cc->geom.x,
cc->geom.y, cc->geom.width, cc->geom.height); cc->geom.y, cc->geom.width, cc->geom.height);
xu_configure(cc); xev_reconfig(cc);
} }
void void
client_move(struct client_ctx *cc) client_move(struct client_ctx *cc)
{ {
XMoveWindow(X_Dpy, cc->win, cc->geom.x, cc->geom.y); XMoveWindow(X_Dpy, cc->win, cc->geom.x, cc->geom.y);
xu_configure(cc); xev_reconfig(cc);
} }
void void
@@ -477,9 +435,6 @@ client_ptrsave(struct client_ctx *cc)
if (client_inbound(cc, x, y)) { if (client_inbound(cc, x, y)) {
cc->ptr.x = x; cc->ptr.x = x;
cc->ptr.y = y; cc->ptr.y = y;
} else {
cc->ptr.x = -1;
cc->ptr.y = -1;
} }
} }
@@ -523,7 +478,7 @@ client_draw_border(struct client_ctx *cc)
pixel = sc->color[CWM_COLOR_BORDER_UNGROUP].pixel; pixel = sc->color[CWM_COLOR_BORDER_UNGROUP].pixel;
break; break;
default: default:
pixel = sc->color[CWM_COLOR_BORDER_ACTIVE].pixel; pixel = sc->color[CWM_COLOR_BORDOR_ACTIVE].pixel;
break; break;
} }
else else
@@ -569,8 +524,9 @@ client_setname(struct client_ctx *cc)
char *newname; char *newname;
if (!xu_getstrprop(cc->win, _NET_WM_NAME, &newname)) if (!xu_getstrprop(cc->win, _NET_WM_NAME, &newname))
if (!xu_getstrprop(cc->win, XA_WM_NAME, &newname)) xu_getstrprop(cc->win, XA_WM_NAME, &newname);
newname = emptystring; if (newname == NULL)
newname = emptystring;
TAILQ_FOREACH(wn, &cc->nameq, entry) TAILQ_FOREACH(wn, &cc->nameq, entry)
if (strcmp(wn->name, newname) == 0) { if (strcmp(wn->name, newname) == 0) {
@@ -598,10 +554,12 @@ match:
xfree(wn); xfree(wn);
cc->nameqlen--; cc->nameqlen--;
} }
return;
} }
void struct client_ctx *
client_cycle(struct screen_ctx *sc, int flags) client_cycle(struct screen_ctx *sc, int reverse)
{ {
struct client_ctx *oldcc, *newcc; struct client_ctx *oldcc, *newcc;
int again = 1; int again = 1;
@@ -610,28 +568,27 @@ client_cycle(struct screen_ctx *sc, int flags)
/* If no windows then you cant cycle */ /* If no windows then you cant cycle */
if (TAILQ_EMPTY(&sc->mruq)) if (TAILQ_EMPTY(&sc->mruq))
return; return (NULL);
if (oldcc == NULL) if (oldcc == NULL)
oldcc = (flags & CWM_RCYCLE ? TAILQ_LAST(&sc->mruq, cycle_entry_q) : oldcc = (reverse ? TAILQ_LAST(&sc->mruq, cycle_entry_q) :
TAILQ_FIRST(&sc->mruq)); TAILQ_FIRST(&sc->mruq));
newcc = oldcc; newcc = oldcc;
while (again) { while (again) {
again = 0; again = 0;
newcc = (flags & CWM_RCYCLE ? client_mruprev(newcc) : newcc = (reverse ? client_mruprev(newcc) :
client_mrunext(newcc)); client_mrunext(newcc));
/* Only cycle visible and non-ignored windows. */ /* Only cycle visible and non-ignored windows. */
if ((newcc->flags & (CLIENT_HIDDEN|CLIENT_IGNORE)) if (newcc->flags & (CLIENT_HIDDEN|CLIENT_IGNORE))
|| ((flags & CWM_INGROUP) && (newcc->group != oldcc->group)))
again = 1; again = 1;
/* Is oldcc the only non-hidden window? */ /* Is oldcc the only non-hidden window? */
if (newcc == oldcc) { if (newcc == oldcc) {
if (again) if (again)
return; /* No windows visible. */ return (NULL); /* No windows visible. */
break; break;
} }
@@ -641,6 +598,8 @@ client_cycle(struct screen_ctx *sc, int flags)
sc->altpersist = 1; sc->altpersist = 1;
client_ptrsave(oldcc); client_ptrsave(oldcc);
client_ptrwarp(newcc); client_ptrwarp(newcc);
return (newcc);
} }
static struct client_ctx * static struct client_ctx *
@@ -759,36 +718,36 @@ client_getsizehints(struct client_ctx *cc)
cc->size->flags = PSize; cc->size->flags = PSize;
if (cc->size->flags & PBaseSize) { if (cc->size->flags & PBaseSize) {
cc->hint.basew = cc->size->base_width; cc->geom.basew = cc->size->base_width;
cc->hint.baseh = cc->size->base_height; cc->geom.baseh = cc->size->base_height;
} else if (cc->size->flags & PMinSize) { } else if (cc->size->flags & PMinSize) {
cc->hint.basew = cc->size->min_width; cc->geom.basew = cc->size->min_width;
cc->hint.baseh = cc->size->min_height; cc->geom.baseh = cc->size->min_height;
} }
if (cc->size->flags & PMinSize) { if (cc->size->flags & PMinSize) {
cc->hint.minw = cc->size->min_width; cc->geom.minw = cc->size->min_width;
cc->hint.minh = cc->size->min_height; cc->geom.minh = cc->size->min_height;
} else if (cc->size->flags & PBaseSize) { } else if (cc->size->flags & PBaseSize) {
cc->hint.minw = cc->size->base_width; cc->geom.minw = cc->size->base_width;
cc->hint.minh = cc->size->base_height; cc->geom.minh = cc->size->base_height;
} }
if (cc->size->flags & PMaxSize) { if (cc->size->flags & PMaxSize) {
cc->hint.maxw = cc->size->max_width; cc->geom.maxw = cc->size->max_width;
cc->hint.maxh = cc->size->max_height; cc->geom.maxh = cc->size->max_height;
} }
if (cc->size->flags & PResizeInc) { if (cc->size->flags & PResizeInc) {
cc->hint.incw = cc->size->width_inc; cc->geom.incw = cc->size->width_inc;
cc->hint.inch = cc->size->height_inc; cc->geom.inch = cc->size->height_inc;
} }
cc->hint.incw = MAX(1, cc->hint.incw); cc->geom.incw = MAX(1, cc->geom.incw);
cc->hint.inch = MAX(1, cc->hint.inch); cc->geom.inch = MAX(1, cc->geom.inch);
if (cc->size->flags & PAspect) { if (cc->size->flags & PAspect) {
if (cc->size->min_aspect.x > 0) if (cc->size->min_aspect.x > 0)
cc->hint.mina = (float)cc->size->min_aspect.y / cc->geom.mina = (float)cc->size->min_aspect.y /
cc->size->min_aspect.x; cc->size->min_aspect.x;
if (cc->size->max_aspect.y > 0) if (cc->size->max_aspect.y > 0)
cc->hint.maxa = (float)cc->size->max_aspect.x / cc->geom.maxa = (float)cc->size->max_aspect.x /
cc->size->max_aspect.y; cc->size->max_aspect.y;
} }
} }
@@ -797,54 +756,56 @@ client_applysizehints(struct client_ctx *cc)
{ {
Bool baseismin; Bool baseismin;
baseismin = (cc->hint.basew == cc->hint.minw) && baseismin = (cc->geom.basew == cc->geom.minw) &&
(cc->hint.baseh == cc->hint.minh); (cc->geom.baseh == cc->geom.minh);
/* temporarily remove base dimensions, ICCCM 4.1.2.3 */ /* temporarily remove base dimensions, ICCCM 4.1.2.3 */
if (!baseismin) { if (!baseismin) {
cc->geom.width -= cc->hint.basew; cc->geom.width -= cc->geom.basew;
cc->geom.height -= cc->hint.baseh; cc->geom.height -= cc->geom.baseh;
} }
/* adjust for aspect limits */ /* adjust for aspect limits */
if (cc->hint.mina > 0 && cc->hint.maxa > 0) { if (cc->geom.mina > 0 && cc->geom.maxa > 0) {
if (cc->hint.maxa < if (cc->geom.maxa <
(float)cc->geom.width / cc->geom.height) (float)cc->geom.width / cc->geom.height)
cc->geom.width = cc->geom.height * cc->hint.maxa; cc->geom.width = cc->geom.height * cc->geom.maxa;
else if (cc->hint.mina < else if (cc->geom.mina <
(float)cc->geom.height / cc->geom.width) (float)cc->geom.height / cc->geom.width)
cc->geom.height = cc->geom.width * cc->hint.mina; cc->geom.height = cc->geom.width * cc->geom.mina;
} }
/* remove base dimensions for increment */ /* remove base dimensions for increment */
if (baseismin) { if (baseismin) {
cc->geom.width -= cc->hint.basew; cc->geom.width -= cc->geom.basew;
cc->geom.height -= cc->hint.baseh; cc->geom.height -= cc->geom.baseh;
} }
/* adjust for increment value */ /* adjust for increment value */
cc->geom.width -= cc->geom.width % cc->hint.incw; cc->geom.width -= cc->geom.width % cc->geom.incw;
cc->geom.height -= cc->geom.height % cc->hint.inch; cc->geom.height -= cc->geom.height % cc->geom.inch;
/* restore base dimensions */ /* restore base dimensions */
cc->geom.width += cc->hint.basew; cc->geom.width += cc->geom.basew;
cc->geom.height += cc->hint.baseh; cc->geom.height += cc->geom.baseh;
/* adjust for min width/height */ /* adjust for min width/height */
cc->geom.width = MAX(cc->geom.width, cc->hint.minw); cc->geom.width = MAX(cc->geom.width, cc->geom.minw);
cc->geom.height = MAX(cc->geom.height, cc->hint.minh); cc->geom.height = MAX(cc->geom.height, cc->geom.minh);
/* adjust for max width/height */ /* adjust for max width/height */
if (cc->hint.maxw) if (cc->geom.maxw)
cc->geom.width = MIN(cc->geom.width, cc->hint.maxw); cc->geom.width = MIN(cc->geom.width, cc->geom.maxw);
if (cc->hint.maxh) if (cc->geom.maxh)
cc->geom.height = MIN(cc->geom.height, cc->hint.maxh); cc->geom.height = MIN(cc->geom.height, cc->geom.maxh);
} }
static void static void
client_gethints(struct client_ctx *cc) client_gethints(struct client_ctx *cc)
{ {
XClassHint xch; XClassHint xch;
int argc;
char **argv;
struct mwm_hints *mwmh; struct mwm_hints *mwmh;
if (XGetClassHint(X_Dpy, cc->win, &xch)) { if (XGetClassHint(X_Dpy, cc->win, &xch)) {
@@ -860,6 +821,29 @@ client_gethints(struct client_ctx *cc)
!(mwmh->decorations & MWM_DECOR_ALL) && !(mwmh->decorations & MWM_DECOR_ALL) &&
!(mwmh->decorations & MWM_DECOR_BORDER)) !(mwmh->decorations & MWM_DECOR_BORDER))
cc->bwidth = 0; cc->bwidth = 0;
if (XGetCommand(X_Dpy, cc->win, &argv, &argc)) {
#define MAX_ARGLEN 512
#define ARG_SEP_ " "
int i, o, len = MAX_ARGLEN;
char *buf;
buf = xmalloc(len);
buf[0] = '\0';
for (o = 0, i = 0; o < len && i < argc; i++) {
if (argv[i] == NULL)
break;
strlcat(buf, argv[i], len);
o += strlen(buf);
strlcat(buf, ARG_SEP_, len);
o += strlen(ARG_SEP_);
}
if (strlen(buf) > 0)
cc->app_cliarg = buf;
XFreeStringList(argv);
}
} }
static void static void
@@ -869,21 +853,7 @@ client_freehints(struct client_ctx *cc)
XFree(cc->app_name); XFree(cc->app_name);
if (cc->app_class != NULL) if (cc->app_class != NULL)
XFree(cc->app_class); XFree(cc->app_class);
} xfree(cc->app_cliarg);
void
client_transient(struct client_ctx *cc)
{
struct client_ctx *tc;
Window trans;
if (XGetTransientForHint(X_Dpy, cc->win, &trans)) {
if ((tc = client_find(trans)) && tc->group) {
group_movetogroup(cc, tc->group->shortcut - 1);
if (tc->flags & CLIENT_IGNORE)
cc->flags |= CLIENT_IGNORE;
}
}
} }
static int static int
@@ -892,32 +862,3 @@ client_inbound(struct client_ctx *cc, int x, int y)
return (x < cc->geom.width && x >= 0 && return (x < cc->geom.width && x >= 0 &&
y < cc->geom.height && y >= 0); y < cc->geom.height && y >= 0);
} }
int
client_snapcalc(int n, int dn, int nmax, int bwidth, int snapdist)
{
int n0, n1, s0, s1;
s0 = s1 = 0;
n0 = n;
n1 = n + dn + (bwidth * 2);
if (abs(n0) <= snapdist)
s0 = -n0;
if (nmax - snapdist <= n1 && n1 <= nmax + snapdist)
s1 = nmax - n1;
/* possible to snap in both directions */
if (s0 != 0 && s1 != 0)
if (abs(s0) < abs(s1))
return s0;
else
return s1;
else if (s0 != 0)
return s0;
else if (s1 != 0)
return s1;
else
return 0;
}

125
conf.c
View File

@@ -15,7 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $OpenBSD$ * $Id$
*/ */
#include <sys/param.h> #include <sys/param.h>
@@ -31,6 +31,13 @@
#include "calmwm.h" #include "calmwm.h"
#ifndef timespeccmp
#define timespeccmp(tsp, usp, cmp) \
(((tsp)->tv_sec == (usp)->tv_sec) ? \
((tsp)->tv_nsec cmp (usp)->tv_nsec) : \
((tsp)->tv_sec cmp (usp)->tv_sec))
#endif
static void conf_mouseunbind(struct conf *, struct mousebinding *); static void conf_mouseunbind(struct conf *, struct mousebinding *);
static void conf_unbind(struct conf *, struct keybinding *); static void conf_unbind(struct conf *, struct keybinding *);
@@ -41,14 +48,14 @@ conf_cmd_add(struct conf *c, char *image, char *label, int flags)
/* "term" and "lock" have special meanings. */ /* "term" and "lock" have special meanings. */
if (strcmp(label, "term") == 0) if (strcmp(label, "term") == 0)
(void)strlcpy(c->termpath, image, sizeof(c->termpath)); strlcpy(c->termpath, image, sizeof(c->termpath));
else if (strcmp(label, "lock") == 0) else if (strcmp(label, "lock") == 0)
(void)strlcpy(c->lockpath, image, sizeof(c->lockpath)); strlcpy(c->lockpath, image, sizeof(c->lockpath));
else { else {
struct cmd *cmd = xmalloc(sizeof(*cmd)); struct cmd *cmd = xmalloc(sizeof(*cmd));
cmd->flags = flags; cmd->flags = flags;
(void)strlcpy(cmd->image, image, sizeof(cmd->image)); strlcpy(cmd->image, image, sizeof(cmd->image));
(void)strlcpy(cmd->label, label, sizeof(cmd->label)); strlcpy(cmd->label, label, sizeof(cmd->label));
TAILQ_INSERT_TAIL(&c->cmdq, cmd, entry); TAILQ_INSERT_TAIL(&c->cmdq, cmd, entry);
} }
} }
@@ -62,20 +69,10 @@ conf_gap(struct conf *c, struct screen_ctx *sc)
void void
conf_font(struct conf *c, struct screen_ctx *sc) conf_font(struct conf *c, struct screen_ctx *sc)
{ {
font_init(sc, c->color[CWM_COLOR_FONT].name); sc->font = font_make(sc, c->DefaultFontName);
sc->font = font_make(sc, c->font); sc->fontheight = font_ascent(sc) + font_descent(sc) + 1;
} }
static struct color color_binds[] = {
{ "#CCCCCC", 0 }, /* CWM_COLOR_BORDER_ACTIVE */
{ "#666666", 0 }, /* CWM_COLOR_BORDER_INACTIVE */
{ "blue", 0 }, /* CWM_COLOR_BORDER_GROUP */
{ "red", 0 }, /* CWM_COLOR_BORDER_UNGROUP */
{ "black", 0 }, /* CWM_COLOR_FG_MENU */
{ "white", 0 }, /* CWM_COLOR_BG_MENU */
{ "black", 0 }, /* CWM_COLOR_FONT */
};
void void
conf_color(struct conf *c, struct screen_ctx *sc) conf_color(struct conf *c, struct screen_ctx *sc)
{ {
@@ -98,14 +95,13 @@ conf_reload(struct conf *c)
return; return;
} }
TAILQ_FOREACH(cc, &Clientq, entry)
client_draw_border(cc);
TAILQ_FOREACH(sc, &Screenq, entry) { TAILQ_FOREACH(sc, &Screenq, entry) {
conf_gap(c, sc); conf_gap(c, sc);
conf_color(c, sc); conf_color(c, sc);
conf_font(c, sc); conf_font(c, sc);
menu_init(sc);
} }
TAILQ_FOREACH(cc, &Clientq, entry)
client_draw_border(cc);
} }
static struct { static struct {
@@ -142,7 +138,6 @@ static struct {
{ "CM-f", "maximize" }, { "CM-f", "maximize" },
{ "CM-equal", "vmaximize" }, { "CM-equal", "vmaximize" },
{ "CMS-equal", "hmaximize" }, { "CMS-equal", "hmaximize" },
{ "CMS-f", "freeze" },
{ "CMS-r", "reload" }, { "CMS-r", "reload" },
{ "CMS-q", "quit" }, { "CMS-q", "quit" },
{ "M-h", "moveleft" }, { "M-h", "moveleft" },
@@ -189,7 +184,6 @@ conf_init(struct conf *c)
c->flags = 0; c->flags = 0;
c->bwidth = CONF_BWIDTH; c->bwidth = CONF_BWIDTH;
c->mamount = CONF_MAMOUNT; c->mamount = CONF_MAMOUNT;
c->snapdist = CONF_SNAPDIST;
TAILQ_INIT(&c->ignoreq); TAILQ_INIT(&c->ignoreq);
TAILQ_INIT(&c->cmdq); TAILQ_INIT(&c->cmdq);
@@ -197,20 +191,30 @@ conf_init(struct conf *c)
TAILQ_INIT(&c->autogroupq); TAILQ_INIT(&c->autogroupq);
TAILQ_INIT(&c->mousebindingq); TAILQ_INIT(&c->mousebindingq);
for (i = 0; i < nitems(kb_binds); i++) for (i = 0; i < sizeof(kb_binds) / sizeof(kb_binds[0]); i++)
conf_bindname(c, kb_binds[i].key, kb_binds[i].func); conf_bindname(c, kb_binds[i].key, kb_binds[i].func);
for (i = 0; i < nitems(m_binds); i++) for (i = 0; i < sizeof(m_binds) / sizeof(m_binds[0]); i++)
conf_mousebind(c, m_binds[i].key, m_binds[i].func); conf_mousebind(c, m_binds[i].key, m_binds[i].func);
for (i = 0; i < nitems(color_binds); i++)
c->color[i].name = xstrdup(color_binds[i].name);
/* Default term/lock */ /* Default term/lock */
(void)strlcpy(c->termpath, "xterm", sizeof(c->termpath)); strlcpy(c->termpath, "xterm", sizeof(c->termpath));
(void)strlcpy(c->lockpath, "xlock", sizeof(c->lockpath)); strlcpy(c->lockpath, "xlock", sizeof(c->lockpath));
c->font = xstrdup(CONF_FONT); 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);
} }
void void
@@ -254,39 +258,31 @@ conf_clear(struct conf *c)
for (i = 0; i < CWM_COLOR_MAX; i++) for (i = 0; i < CWM_COLOR_MAX; i++)
xfree(c->color[i].name); xfree(c->color[i].name);
xfree(c->font); xfree(c->DefaultFontName);
} }
void void
conf_setup(struct conf *c, const char *conf_file) conf_setup(struct conf *c, const char *conf_file)
{ {
char *home;
struct stat sb; struct stat sb;
int parse = 0;
if (conf_file == NULL) {
char *home = getenv("HOME");
if (home == NULL)
errx(1, "No HOME directory.");
snprintf(c->conf_path, sizeof(c->conf_path), "%s/%s", home,
CONFFILE);
} else
if (stat(conf_file, &sb) == -1 || !(sb.st_mode & S_IFREG))
errx(1, "%s: %s", conf_file, strerror(errno));
else
strlcpy(c->conf_path, conf_file, sizeof(c->conf_path));
conf_init(c); conf_init(c);
if (conf_file == NULL) { (void)parse_config(c->conf_path, c);
if ((home = getenv("HOME")) == NULL)
errx(1, "No HOME directory.");
(void)snprintf(c->conf_path, sizeof(c->conf_path), "%s/%s",
home, CONFFILE);
if (stat(c->conf_path, &sb) == 0 && (sb.st_mode & S_IFREG))
parse = 1;
} else {
if (stat(conf_file, &sb) == -1 || !(sb.st_mode & S_IFREG))
errx(1, "%s: %s", conf_file, strerror(errno));
else {
(void)strlcpy(c->conf_path, conf_file,
sizeof(c->conf_path));
parse = 1;
}
}
if (parse && (parse_config(c->conf_path, c) == -1))
warnx("config file %s has errors, not loading", c->conf_path);
} }
void void
@@ -359,15 +355,12 @@ static struct {
{ "movetogroup9", kbfunc_client_movetogroup, KBFLAG_NEEDCLIENT, { "movetogroup9", kbfunc_client_movetogroup, KBFLAG_NEEDCLIENT,
{.i = 9} }, {.i = 9} },
{ "nogroup", kbfunc_client_nogroup, 0, {0} }, { "nogroup", kbfunc_client_nogroup, 0, {0} },
{ "cyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_CYCLE} }, { "cyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_CYCLEGROUP} },
{ "rcyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_RCYCLE} }, { "rcyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_RCYCLEGROUP} },
{ "cycleingroup", kbfunc_client_cycle, KBFLAG_NEEDCLIENT, {.i = CWM_CYCLE|CWM_INGROUP} },
{ "rcycleingroup", kbfunc_client_cycle, KBFLAG_NEEDCLIENT, {.i = CWM_RCYCLE|CWM_INGROUP} },
{ "grouptoggle", kbfunc_client_grouptoggle, KBFLAG_NEEDCLIENT, {0}}, { "grouptoggle", kbfunc_client_grouptoggle, KBFLAG_NEEDCLIENT, {0}},
{ "maximize", kbfunc_client_maximize, KBFLAG_NEEDCLIENT, {0} }, { "maximize", kbfunc_client_maximize, KBFLAG_NEEDCLIENT, {0} },
{ "vmaximize", kbfunc_client_vmaximize, KBFLAG_NEEDCLIENT, {0} }, { "vmaximize", kbfunc_client_vmaximize, KBFLAG_NEEDCLIENT, {0} },
{ "hmaximize", kbfunc_client_hmaximize, KBFLAG_NEEDCLIENT, {0} }, { "hmaximize", kbfunc_client_hmaximize, KBFLAG_NEEDCLIENT, {0} },
{ "freeze", kbfunc_client_freeze, KBFLAG_NEEDCLIENT, {0} },
{ "reload", kbfunc_reload, 0, {0} }, { "reload", kbfunc_reload, 0, {0} },
{ "quit", kbfunc_quit_wm, 0, {0} }, { "quit", kbfunc_quit_wm, 0, {0} },
{ "exec", kbfunc_exec, 0, {.i = CWM_EXEC_PROGRAM} }, { "exec", kbfunc_exec, 0, {.i = CWM_EXEC_PROGRAM} },
@@ -420,6 +413,7 @@ static struct {
{.i = (CWM_LEFT|CWM_PTRMOVE|CWM_BIGMOVE)} }, {.i = (CWM_LEFT|CWM_PTRMOVE|CWM_BIGMOVE)} },
{ "bigptrmoveright", kbfunc_moveresize, 0, { "bigptrmoveright", kbfunc_moveresize, 0,
{.i = (CWM_RIGHT|CWM_PTRMOVE|CWM_BIGMOVE)} }, {.i = (CWM_RIGHT|CWM_PTRMOVE|CWM_BIGMOVE)} },
{ NULL, NULL, 0, {0}},
}; };
/* /*
@@ -473,7 +467,8 @@ conf_bindname(struct conf *c, char *name, char *binding)
current_binding = xcalloc(1, sizeof(*current_binding)); current_binding = xcalloc(1, sizeof(*current_binding));
if ((substring = strchr(name, '-')) != NULL) { if ((substring = strchr(name, '-')) != NULL) {
for (iter = 0; iter < nitems(bind_mods); iter++) { for (iter = 0; iter < (sizeof(bind_mods) /
sizeof(bind_mods[0])); iter++) {
if ((tmp = strchr(name, bind_mods[iter].chr)) != if ((tmp = strchr(name, bind_mods[iter].chr)) !=
NULL && tmp < substring) { NULL && tmp < substring) {
current_binding->modmask |= current_binding->modmask |=
@@ -508,7 +503,7 @@ conf_bindname(struct conf *c, char *name, char *binding)
if (strcmp("unmap", binding) == 0) if (strcmp("unmap", binding) == 0)
return; return;
for (iter = 0; iter < nitems(name_to_kbfunc); iter++) { for (iter = 0; name_to_kbfunc[iter].tag != NULL; iter++) {
if (strcmp(name_to_kbfunc[iter].tag, binding) != 0) if (strcmp(name_to_kbfunc[iter].tag, binding) != 0)
continue; continue;
@@ -525,6 +520,7 @@ conf_bindname(struct conf *c, char *name, char *binding)
current_binding->flags = 0; current_binding->flags = 0;
conf_grab(c, current_binding); conf_grab(c, current_binding);
TAILQ_INSERT_TAIL(&c->keybindingq, current_binding, entry); TAILQ_INSERT_TAIL(&c->keybindingq, current_binding, entry);
return;
} }
static void static void
@@ -559,11 +555,11 @@ static struct {
{ "window_grouptoggle", mousefunc_window_grouptoggle, { "window_grouptoggle", mousefunc_window_grouptoggle,
MOUSEBIND_CTX_WIN }, MOUSEBIND_CTX_WIN },
{ "window_lower", mousefunc_window_lower, MOUSEBIND_CTX_WIN }, { "window_lower", mousefunc_window_lower, MOUSEBIND_CTX_WIN },
{ "window_raise", mousefunc_window_raise, MOUSEBIND_CTX_WIN },
{ "window_hide", mousefunc_window_hide, MOUSEBIND_CTX_WIN }, { "window_hide", mousefunc_window_hide, MOUSEBIND_CTX_WIN },
{ "menu_group", mousefunc_menu_group, MOUSEBIND_CTX_ROOT }, { "menu_group", mousefunc_menu_group, MOUSEBIND_CTX_ROOT },
{ "menu_unhide", mousefunc_menu_unhide, MOUSEBIND_CTX_ROOT }, { "menu_unhide", mousefunc_menu_unhide, MOUSEBIND_CTX_ROOT },
{ "menu_cmd", mousefunc_menu_cmd, MOUSEBIND_CTX_ROOT }, { "menu_cmd", mousefunc_menu_cmd, MOUSEBIND_CTX_ROOT },
{ NULL, NULL, 0 },
}; };
void void
@@ -577,7 +573,8 @@ conf_mousebind(struct conf *c, char *name, char *binding)
current_binding = xcalloc(1, sizeof(*current_binding)); current_binding = xcalloc(1, sizeof(*current_binding));
if ((substring = strchr(name, '-')) != NULL) { if ((substring = strchr(name, '-')) != NULL) {
for (iter = 0; iter < nitems(bind_mods); iter++) { for (iter = 0; iter < (sizeof(bind_mods) /
sizeof(bind_mods[0])); iter++) {
if ((tmp = strchr(name, bind_mods[iter].chr)) != if ((tmp = strchr(name, bind_mods[iter].chr)) !=
NULL && tmp < substring) { NULL && tmp < substring) {
current_binding->modmask |= current_binding->modmask |=
@@ -599,7 +596,7 @@ conf_mousebind(struct conf *c, char *name, char *binding)
if (strcmp("unmap", binding) == 0) if (strcmp("unmap", binding) == 0)
return; return;
for (iter = 0; iter < nitems(name_to_mousefunc); iter++) { for (iter = 0; name_to_mousefunc[iter].tag != NULL; iter++) {
if (strcmp(name_to_mousefunc[iter].tag, binding) != 0) if (strcmp(name_to_mousefunc[iter].tag, binding) != 0)
continue; continue;

4
cwm.1
View File

@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" .\"
.Dd $Mdocdate: September 25 2010 $ .Dd $Mdocdate: August 24 2009 $
.Dt CWM 1 .Dt CWM 1
.Os .Os
.Sh NAME .Sh NAME
@@ -88,8 +88,6 @@ Toggle group membership of current window.
Cycle through active groups. Cycle through active groups.
.It Ic M-Left .It Ic M-Left
Reverse cycle through active groups. Reverse cycle through active groups.
.It Ic CMS-f
Toggle freezing geometry of current window.
.It Ic CM-f .It Ic CM-f
Toggle full-screen size of current window. Toggle full-screen size of current window.
.It Ic CM-= .It Ic CM-=

37
cwmrc.5
View File

@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\" .\"
.Dd $Mdocdate: September 8 2011 $ .Dd $Mdocdate: September 25 2010 $
.Dt CWMRC 5 .Dt CWMRC 5
.Os .Os
.Sh NAME .Sh NAME
@@ -24,19 +24,7 @@
This manual page describes the This manual page describes the
.Xr cwm 1 .Xr cwm 1
configuration file. configuration file.
.Pp The following options are accepted in the configuration file:
The current line can be extended over multiple lines using a backslash
.Pq Sq \e .
Comments can be put anywhere in the file using a hash mark
.Pq Sq # ,
and extend to the end of the current line.
Care should be taken when commenting out multi-line text:
the comment is effective until the end of the entire block.
.Pp
Arguments containing whitespace should be surrounded by double quotes
.Pq \&" .
.Pp
The following options are accepted:
.Pp .Pp
.Bl -tag -width Ds -compact .Bl -tag -width Ds -compact
.It Ic autogroup Ar group windowname .It Ic autogroup Ar group windowname
@@ -99,21 +87,12 @@ Set the window border width to
.It Ic color activeborder Ar color .It Ic color activeborder Ar color
Set the color of the active border. Set the color of the active border.
.Pp .Pp
.It Ic color font Ar color
Set menu font color.
.Pp
.It Ic color groupborder Ar color .It Ic color groupborder Ar color
Set the color of the border while grouping a window. Set the color of the border while grouping a window.
.Pp .Pp
.It Ic color inactiveborder Ar color .It Ic color inactiveborder Ar color
Set the color of the inactive border. Set the color of the inactive border.
.Pp .Pp
.It Ic color menubg Ar color
Set menu background color.
.Pp
.It Ic color menufg Ar color
Set menu foreground color.
.Pp
.It Ic color ungroupborder Ar color .It Ic color ungroupborder Ar color
Set the color of the border while ungrouping a window. Set the color of the border while ungrouping a window.
.Pp .Pp
@@ -206,10 +185,6 @@ Set a default size for the keyboard movement bindings,
in pixels. in pixels.
The default is 1. The default is 1.
.Pp .Pp
.It Ic snapdist Ar pixels
Minimum distance to snap-to adjacent edge, in pixels.
The default is 0.
.Pp
.It Ic sticky Ic yes Ns \&| Ns Ic no .It Ic sticky Ic yes Ns \&| Ns Ic no
Toggle sticky group mode. Toggle sticky group mode.
The default behavior for new windows is to not assign any group. The default behavior for new windows is to not assign any group.
@@ -302,10 +277,6 @@ Reverse cycle through groups.
Forward cycle through windows. Forward cycle through windows.
.It rcycle .It rcycle
Reverse cycle through windows. Reverse cycle through windows.
.It cycleingroup
Forward cycle through windows in current group.
.It rcycleingroup
Reverse cycle through windows in current group.
.It delete .It delete
Delete current window. Delete current window.
.It hide .It hide
@@ -316,8 +287,6 @@ Lower current window.
Raise current window. Raise current window.
.It label .It label
Label current window. Label current window.
.It freeze
Freeze current window geometry.
.It maximize .It maximize
Maximize current window full-screen. Maximize current window full-screen.
.It vmaximize .It vmaximize
@@ -429,8 +398,6 @@ Move current window.
Resize current window. Resize current window.
.It window_lower .It window_lower
Lower current window. Lower current window.
.It window_raise
Raise current window.
.It window_hide .It window_hide
Hide current window. Hide current window.
.It window_grouptoggle .It window_grouptoggle

20
font.c
View File

@@ -1,5 +1,5 @@
/* /*
* calmwm - the calm window manager * font.c - cwm font abstraction
* *
* Copyright (c) 2005 Marius Eriksen <marius@monkey.org> * Copyright (c) 2005 Marius Eriksen <marius@monkey.org>
* *
@@ -14,8 +14,6 @@
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $OpenBSD$
*/ */
#include <sys/param.h> #include <sys/param.h>
@@ -45,24 +43,19 @@ font_descent(struct screen_ctx *sc)
u_int u_int
font_height(struct screen_ctx *sc) font_height(struct screen_ctx *sc)
{ {
return (sc->font->height + 1); return (sc->fontheight);
} }
void void
font_init(struct screen_ctx *sc, const char *color) font_init(struct screen_ctx *sc)
{ {
if (sc->xftdraw)
XftDrawDestroy(sc->xftdraw);
sc->xftdraw = XftDrawCreate(X_Dpy, sc->rootwin, sc->xftdraw = XftDrawCreate(X_Dpy, sc->rootwin,
DefaultVisual(X_Dpy, sc->which), DefaultColormap(X_Dpy, sc->which)); DefaultVisual(X_Dpy, sc->which), DefaultColormap(X_Dpy, sc->which));
if (sc->xftdraw == NULL) if (sc->xftdraw == NULL)
errx(1, "XftDrawCreate"); errx(1, "XftDrawCreate");
if (sc->xftcolor.pixel)
XftColorFree(X_Dpy, DefaultVisual(X_Dpy, sc->which),
DefaultColormap(X_Dpy, sc->which), &sc->xftcolor);
if (!XftColorAllocName(X_Dpy, DefaultVisual(X_Dpy, sc->which), if (!XftColorAllocName(X_Dpy, DefaultVisual(X_Dpy, sc->which),
DefaultColormap(X_Dpy, sc->which), color, &sc->xftcolor)) DefaultColormap(X_Dpy, sc->which), "black", &sc->xftcolor))
errx(1, "XftColorAllocName"); errx(1, "XftColorAllocName");
} }
@@ -71,7 +64,7 @@ font_width(struct screen_ctx *sc, const char *text, int len)
{ {
XGlyphInfo extents; XGlyphInfo extents;
XftTextExtentsUtf8(X_Dpy, sc->font, (const FcChar8*)text, XftTextExtents8(X_Dpy, sc->font, (const XftChar8*)text,
len, &extents); len, &extents);
return (extents.xOff); return (extents.xOff);
@@ -82,7 +75,8 @@ font_draw(struct screen_ctx *sc, const char *text, int len,
Drawable d, int x, int y) Drawable d, int x, int y)
{ {
XftDrawChange(sc->xftdraw, d); XftDrawChange(sc->xftdraw, d);
XftDrawStringUtf8(sc->xftdraw, &sc->xftcolor, sc->font, x, y, /* Really needs to be UTF8'd. */
XftDrawString8(sc->xftdraw, &sc->xftcolor, sc->font, x, y,
(const FcChar8*)text, len); (const FcChar8*)text, len);
} }

35
group.c
View File

@@ -16,7 +16,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $OpenBSD$ * $Id$
*/ */
#include <sys/param.h> #include <sys/param.h>
@@ -108,11 +108,6 @@ group_show(struct screen_ctx *sc, struct group_ctx *gc)
u_int i; u_int i;
int lastempty = -1; int lastempty = -1;
gc->highstack = 0;
TAILQ_FOREACH(cc, &gc->clients, group_entry) {
if (cc->stackingorder > gc->highstack)
gc->highstack = cc->stackingorder;
}
winlist = (Window *) xcalloc(sizeof(*winlist), (gc->highstack + 1)); winlist = (Window *) xcalloc(sizeof(*winlist), (gc->highstack + 1));
/* /*
@@ -216,19 +211,13 @@ void
group_movetogroup(struct client_ctx *cc, int idx) group_movetogroup(struct client_ctx *cc, int idx)
{ {
struct screen_ctx *sc = cc->sc; struct screen_ctx *sc = cc->sc;
struct group_ctx *gc;
if (idx < 0 || idx >= CALMWM_NGROUPS) if (idx < 0 || idx >= CALMWM_NGROUPS)
err(1, "group_movetogroup: index out of range (%d)", idx); err(1, "group_movetogroup: index out of range (%d)", idx);
gc = &sc->groups[idx]; if(sc->group_active != &sc->groups[idx])
if (cc->group == gc)
return;
if (gc->hidden) {
client_hide(cc); client_hide(cc);
gc->nhidden++; group_add(&sc->groups[idx], cc);
}
group_add(gc, cc);
} }
/* /*
@@ -319,7 +308,7 @@ group_only(struct screen_ctx *sc, int idx)
* Cycle through active groups. If none exist, then just stay put. * Cycle through active groups. If none exist, then just stay put.
*/ */
void void
group_cycle(struct screen_ctx *sc, int flags) group_cycle(struct screen_ctx *sc, int reverse)
{ {
struct group_ctx *gc, *showgroup = NULL; struct group_ctx *gc, *showgroup = NULL;
@@ -327,11 +316,11 @@ group_cycle(struct screen_ctx *sc, int flags)
gc = sc->group_active; gc = sc->group_active;
for (;;) { for (;;) {
gc = (flags & CWM_RCYCLE) ? TAILQ_PREV(gc, group_ctx_q, gc = reverse ? TAILQ_PREV(gc, group_ctx_q, entry) :
entry) : TAILQ_NEXT(gc, entry); TAILQ_NEXT(gc, entry);
if (gc == NULL) if (gc == NULL)
gc = (flags & CWM_RCYCLE) ? TAILQ_LAST(&sc->groupq, gc = reverse ? TAILQ_LAST(&sc->groupq, group_ctx_q) :
group_ctx_q) : TAILQ_FIRST(&sc->groupq); TAILQ_FIRST(&sc->groupq);
if (gc == sc->group_active) if (gc == sc->group_active)
break; break;
@@ -383,10 +372,10 @@ group_menu(XButtonEvent *e)
mi = xcalloc(1, sizeof(*mi)); mi = xcalloc(1, sizeof(*mi));
if (gc->hidden) if (gc->hidden)
(void)snprintf(mi->text, sizeof(mi->text), "%d: [%s]", snprintf(mi->text, sizeof(mi->text), "%d: [%s]",
gc->shortcut, sc->group_names[i]); gc->shortcut, sc->group_names[i]);
else else
(void)snprintf(mi->text, sizeof(mi->text), "%d: %s", snprintf(mi->text, sizeof(mi->text), "%d: %s",
gc->shortcut, sc->group_names[i]); gc->shortcut, sc->group_names[i]);
mi->ctx = gc; mi->ctx = gc;
TAILQ_INSERT_TAIL(&menuq, mi, entry); TAILQ_INSERT_TAIL(&menuq, mi, entry);
@@ -517,7 +506,7 @@ group_update_names(struct screen_ctx *sc)
if (prop_ret != NULL) if (prop_ret != NULL)
XFree(prop_ret); XFree(prop_ret);
if (sc->group_nonames != 0) if (sc->group_nonames != 0)
xfree(sc->group_names); free(sc->group_names);
sc->group_names = strings; sc->group_names = strings;
sc->group_nonames = n; sc->group_nonames = n;
@@ -539,7 +528,7 @@ group_set_names(struct screen_ctx *sc)
tlen = len; tlen = len;
for (i = 0; i < sc->group_nonames; i++) { for (i = 0; i < sc->group_nonames; i++) {
slen = strlen(sc->group_names[i]) + 1; slen = strlen(sc->group_names[i]) + 1;
(void)strlcpy(q, sc->group_names[i], tlen); strlcpy(q, sc->group_names[i], tlen);
tlen -= slen; tlen -= slen;
q += slen; q += slen;
} }

117
input.c Normal file
View File

@@ -0,0 +1,117 @@
/*
* calmwm - the calm window manager
*
* Copyright (c) 2004 Marius Aamodt 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.
*
* $Id$
*/
#include <sys/param.h>
#include <sys/queue.h>
#include <err.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "calmwm.h"
int
input_keycodetrans(KeyCode kc, u_int state, enum ctltype *ctl, char *chr)
{
int ks;
*ctl = CTL_NONE;
*chr = '\0';
ks = XKeycodeToKeysym(X_Dpy, kc, (state & ShiftMask) ? 1 : 0);
/* Look for control characters. */
switch (ks) {
case XK_BackSpace:
*ctl = CTL_ERASEONE;
break;
case XK_Return:
*ctl = CTL_RETURN;
break;
case XK_Up:
*ctl = CTL_UP;
break;
case XK_Down:
*ctl = CTL_DOWN;
break;
case XK_Escape:
*ctl = CTL_ABORT;
break;
}
if (*ctl == CTL_NONE && (state & ControlMask)) {
switch (ks) {
case XK_s:
case XK_S:
/* Emacs "next" */
*ctl = CTL_DOWN;
break;
case XK_r:
case XK_R:
/* Emacs "previous" */
*ctl = CTL_UP;
break;
case XK_u:
case XK_U:
*ctl = CTL_WIPE;
break;
case XK_h:
case XK_H:
*ctl = CTL_ERASEONE;
break;
case XK_a:
case XK_A:
*ctl = CTL_ALL;
break;
}
}
if (*ctl == CTL_NONE && (state & Mod1Mask)) {
switch (ks) {
case XK_j:
case XK_J:
/* Vi "down" */
*ctl = CTL_DOWN;
break;
case XK_k:
case XK_K:
/* Vi "up" */
*ctl = CTL_UP;
break;
}
}
if (*ctl != CTL_NONE)
return (0);
/*
* For regular characters, only (part of, actually) Latin 1
* for now.
*/
if (ks < 0x20 || ks > 0x07e)
return (-1);
*chr = (char)ks;
return (0);
}

View File

@@ -1,7 +1,7 @@
/* /*
* calmwm - the calm window manager * calmwm - the calm window manager
* *
* Copyright (c) 2004 Martin Murray <mmurray@monkey.org> * Copyright (c) 2004 Martin Murray <mmurray@monkey.org>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -15,7 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $OpenBSD$ * $Id$
*/ */
#include <sys/param.h> #include <sys/param.h>
@@ -25,7 +25,6 @@
#include <err.h> #include <err.h>
#include <errno.h> #include <errno.h>
#include <paths.h> #include <paths.h>
#include <signal.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
@@ -36,7 +35,7 @@
#define KNOWN_HOSTS ".ssh/known_hosts" #define KNOWN_HOSTS ".ssh/known_hosts"
#define HASH_MARKER "|1|" #define HASH_MARKER "|1|"
extern sig_atomic_t xev_quit; extern int _xev_quit;
void void
kbfunc_client_lower(struct client_ctx *cc, union arg *arg) kbfunc_client_lower(struct client_ctx *cc, union arg *arg)
@@ -50,8 +49,8 @@ kbfunc_client_raise(struct client_ctx *cc, union arg *arg)
client_raise(cc); client_raise(cc);
} }
#define TYPEMASK (CWM_MOVE | CWM_RESIZE | CWM_PTRMOVE) #define typemask (CWM_MOVE | CWM_RESIZE | CWM_PTRMOVE)
#define MOVEMASK (CWM_UP | CWM_DOWN | CWM_LEFT | CWM_RIGHT) #define movemask (CWM_UP | CWM_DOWN | CWM_LEFT | CWM_RIGHT)
void void
kbfunc_moveresize(struct client_ctx *cc, union arg *arg) kbfunc_moveresize(struct client_ctx *cc, union arg *arg)
{ {
@@ -59,9 +58,6 @@ kbfunc_moveresize(struct client_ctx *cc, union arg *arg)
int x, y, flags, amt; int x, y, flags, amt;
u_int mx, my; u_int mx, my;
if (cc->flags & CLIENT_FREEZE)
return;
sc = cc->sc; sc = cc->sc;
mx = my = 0; mx = my = 0;
@@ -73,7 +69,7 @@ kbfunc_moveresize(struct client_ctx *cc, union arg *arg)
amt = amt * 10; amt = amt * 10;
} }
switch (flags & MOVEMASK) { switch (flags & movemask) {
case CWM_UP: case CWM_UP:
my -= amt; my -= amt;
break; break;
@@ -87,7 +83,7 @@ kbfunc_moveresize(struct client_ctx *cc, union arg *arg)
mx -= amt; mx -= amt;
break; break;
} }
switch (flags & TYPEMASK) { switch (flags & typemask) {
case CWM_MOVE: case CWM_MOVE:
cc->geom.y += my; cc->geom.y += my;
if (cc->geom.y + cc->geom.height < 0) if (cc->geom.y + cc->geom.height < 0)
@@ -101,13 +97,6 @@ kbfunc_moveresize(struct client_ctx *cc, union arg *arg)
if (cc->geom.x > cc->sc->xmax - 1) if (cc->geom.x > cc->sc->xmax - 1)
cc->geom.x = cc->sc->xmax - 1; cc->geom.x = cc->sc->xmax - 1;
cc->geom.x += client_snapcalc(cc->geom.x,
cc->geom.width, cc->sc->xmax,
cc->bwidth, Conf.snapdist);
cc->geom.y += client_snapcalc(cc->geom.y,
cc->geom.height, cc->sc->ymax,
cc->bwidth, Conf.snapdist);
client_move(cc); client_move(cc);
xu_ptr_getpos(cc->win, &x, &y); xu_ptr_getpos(cc->win, &x, &y);
cc->ptr.y = y + my; cc->ptr.y = y + my;
@@ -130,8 +119,13 @@ kbfunc_moveresize(struct client_ctx *cc, union arg *arg)
client_ptrwarp(cc); client_ptrwarp(cc);
break; break;
case CWM_PTRMOVE: case CWM_PTRMOVE:
xu_ptr_getpos(sc->rootwin, &x, &y); if (cc) {
xu_ptr_setpos(sc->rootwin, x + mx, y + my); xu_ptr_getpos(cc->win, &x, &y);
xu_ptr_setpos(cc->win, x + mx, y + my);
} else {
xu_ptr_getpos(sc->rootwin, &x, &y);
xu_ptr_setpos(sc->rootwin, x + mx, y + my);
}
break; break;
default: default:
warnx("invalid flags passed to kbfunc_client_moveresize"); warnx("invalid flags passed to kbfunc_client_moveresize");
@@ -153,7 +147,7 @@ kbfunc_client_search(struct client_ctx *cc, union arg *arg)
TAILQ_FOREACH(cc, &Clientq, entry) { TAILQ_FOREACH(cc, &Clientq, entry) {
mi = xcalloc(1, sizeof(*mi)); mi = xcalloc(1, sizeof(*mi));
(void)strlcpy(mi->text, cc->name, sizeof(mi->text)); strlcpy(mi->text, cc->name, sizeof(mi->text));
mi->ctx = cc; mi->ctx = cc;
TAILQ_INSERT_TAIL(&menuq, mi, entry); TAILQ_INSERT_TAIL(&menuq, mi, entry);
} }
@@ -188,7 +182,7 @@ kbfunc_menu_search(struct client_ctx *cc, union arg *arg)
TAILQ_FOREACH(cmd, &Conf.cmdq, entry) { TAILQ_FOREACH(cmd, &Conf.cmdq, entry) {
mi = xcalloc(1, sizeof(*mi)); mi = xcalloc(1, sizeof(*mi));
(void)strlcpy(mi->text, cmd->label, sizeof(mi->text)); strlcpy(mi->text, cmd->label, sizeof(mi->text));
mi->ctx = cmd; mi->ctx = cmd;
TAILQ_INSERT_TAIL(&menuq, mi, entry); TAILQ_INSERT_TAIL(&menuq, mi, entry);
} }
@@ -287,7 +281,7 @@ kbfunc_exec(struct client_ctx *cc, union arg *arg)
/* skip everything but regular files and symlinks */ /* skip everything but regular files and symlinks */
if (dp->d_type != DT_REG && dp->d_type != DT_LNK) if (dp->d_type != DT_REG && dp->d_type != DT_LNK)
continue; continue;
(void)memset(tpath, '\0', sizeof(tpath)); memset(tpath, '\0', sizeof(tpath));
l = snprintf(tpath, sizeof(tpath), "%s/%s", paths[i], l = snprintf(tpath, sizeof(tpath), "%s/%s", paths[i],
dp->d_name); dp->d_name);
/* check for truncation etc */ /* check for truncation etc */
@@ -295,8 +289,7 @@ kbfunc_exec(struct client_ctx *cc, union arg *arg)
continue; continue;
if (access(tpath, X_OK) == 0) { if (access(tpath, X_OK) == 0) {
mi = xcalloc(1, sizeof(*mi)); mi = xcalloc(1, sizeof(*mi));
(void)strlcpy(mi->text, strlcpy(mi->text, dp->d_name, sizeof(mi->text));
dp->d_name, sizeof(mi->text));
TAILQ_INSERT_TAIL(&menuq, mi, entry); TAILQ_INSERT_TAIL(&menuq, mi, entry);
} }
} }
@@ -363,7 +356,7 @@ kbfunc_ssh(struct client_ctx *cc, union arg *arg)
else { else {
/* EOF without EOL, copy and add the NUL */ /* EOF without EOL, copy and add the NUL */
lbuf = xmalloc(len + 1); lbuf = xmalloc(len + 1);
(void)memcpy(lbuf, buf, len); memcpy(lbuf, buf, len);
lbuf[len] = '\0'; lbuf[len] = '\0';
buf = lbuf; buf = lbuf;
} }
@@ -376,13 +369,13 @@ kbfunc_ssh(struct client_ctx *cc, union arg *arg)
/* ignore badness */ /* ignore badness */
if (p - buf + 1 > sizeof(hostbuf)) if (p - buf + 1 > sizeof(hostbuf))
continue; continue;
(void)strlcpy(hostbuf, buf, p - buf + 1); (void) strlcpy(hostbuf, buf, p - buf + 1);
mi = xcalloc(1, sizeof(*mi)); mi = xcalloc(1, sizeof(*mi));
(void)strlcpy(mi->text, hostbuf, sizeof(mi->text)); (void) strlcpy(mi->text, hostbuf, sizeof(mi->text));
TAILQ_INSERT_TAIL(&menuq, mi, entry); TAILQ_INSERT_TAIL(&menuq, mi, entry);
} }
xfree(lbuf); xfree(lbuf);
(void)fclose(fp); fclose(fp);
if ((mi = menu_filter(sc, &menuq, "ssh", NULL, 1, if ((mi = menu_filter(sc, &menuq, "ssh", NULL, 1,
search_match_exec, NULL)) != NULL) { search_match_exec, NULL)) != NULL) {
@@ -486,16 +479,10 @@ kbfunc_client_hmaximize(struct client_ctx *cc, union arg *arg)
client_horizmaximize(cc); client_horizmaximize(cc);
} }
void
kbfunc_client_freeze(struct client_ctx *cc, union arg *arg)
{
client_freeze(cc);
}
void void
kbfunc_quit_wm(struct client_ctx *cc, union arg *arg) kbfunc_quit_wm(struct client_ctx *cc, union arg *arg)
{ {
xev_quit = 1; _xev_quit = 1;
} }
void void

199
menu.c
View File

@@ -1,6 +1,4 @@
/* /*
* calmwm - the calm window manager
*
* Copyright (c) 2008 Owain G. Ainsworth <oga@openbsd.org> * Copyright (c) 2008 Owain G. Ainsworth <oga@openbsd.org>
* Copyright (c) 2004 Marius Aamodt Eriksen <marius@monkey.org> * Copyright (c) 2004 Marius Aamodt Eriksen <marius@monkey.org>
* *
@@ -15,8 +13,6 @@
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $OpenBSD$
*/ */
#include <sys/param.h> #include <sys/param.h>
@@ -31,14 +27,8 @@
#include "calmwm.h" #include "calmwm.h"
#define PROMPT_SCHAR "\xc2\xbb" #define PROMPT_SCHAR '<27>'
#define PROMPT_ECHAR "\xc2\xab" #define PROMPT_ECHAR '<27>'
enum ctltype {
CTL_NONE = -1,
CTL_ERASEONE = 0, CTL_WIPE, CTL_UP, CTL_DOWN, CTL_RETURN,
CTL_ABORT, CTL_ALL
};
struct menu_ctx { struct menu_ctx {
char searchstr[MENU_MAXENTRY + 1]; char searchstr[MENU_MAXENTRY + 1];
@@ -68,19 +58,14 @@ static void menu_draw(struct screen_ctx *, struct menu_ctx *,
struct menu_q *, struct menu_q *); struct menu_q *, struct menu_q *);
static int menu_calc_entry(struct screen_ctx *, struct menu_ctx *, static int menu_calc_entry(struct screen_ctx *, struct menu_ctx *,
int, int); int, int);
static int menu_keycode(KeyCode, u_int, enum ctltype *,
char *);
void void
menu_init(struct screen_ctx *sc) menu_init(struct screen_ctx *sc)
{ {
XGCValues gv; XGCValues gv;
if (sc->menuwin) sc->menuwin = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, 1, 1, 0,
XDestroyWindow(X_Dpy, sc->menuwin); sc->color[CWM_COLOR_BG_MENU].pixel,
sc->menuwin = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, 1, 1,
Conf.bwidth,
sc->color[CWM_COLOR_FG_MENU].pixel,
sc->color[CWM_COLOR_BG_MENU].pixel); sc->color[CWM_COLOR_BG_MENU].pixel);
gv.foreground = gv.foreground =
@@ -88,8 +73,6 @@ menu_init(struct screen_ctx *sc)
gv.background = sc->color[CWM_COLOR_BG_MENU].pixel; gv.background = sc->color[CWM_COLOR_BG_MENU].pixel;
gv.function = GXxor; gv.function = GXxor;
if (sc->gc)
XFreeGC(X_Dpy, sc->gc);
sc->gc = XCreateGC(X_Dpy, sc->menuwin, sc->gc = XCreateGC(X_Dpy, sc->menuwin,
GCForeground|GCBackground|GCFunction, &gv); GCForeground|GCBackground|GCFunction, &gv);
} }
@@ -106,7 +89,6 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, char *prompt,
XEvent e; XEvent e;
Window focuswin; Window focuswin;
int evmask, focusrevert; int evmask, focusrevert;
int xsave, ysave, xcur, ycur;
TAILQ_INIT(&resultq); TAILQ_INIT(&resultq);
@@ -114,25 +96,22 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, char *prompt,
xu_ptr_getpos(sc->rootwin, &mc.x, &mc.y); xu_ptr_getpos(sc->rootwin, &mc.x, &mc.y);
xsave = mc.x;
ysave = mc.y;
if (prompt == NULL) { if (prompt == NULL) {
evmask = MENUMASK; evmask = MenuMask;
mc.promptstr[0] = '\0'; mc.promptstr[0] = '\0';
mc.list = 1; mc.list = 1;
} else { } else {
evmask = MENUMASK | KEYMASK; /* only accept keys if prompt */ evmask = MenuMask | KeyMask; /* only accept keys if prompt */
(void)snprintf(mc.promptstr, sizeof(mc.promptstr), "%s%s", snprintf(mc.promptstr, sizeof(mc.promptstr), "%s%c", prompt,
prompt, PROMPT_SCHAR); PROMPT_SCHAR);
(void)snprintf(mc.dispstr, sizeof(mc.dispstr), "%s%s%s", snprintf(mc.dispstr, sizeof(mc.dispstr), "%s%s%c", mc.promptstr,
mc.promptstr, mc.searchstr, PROMPT_ECHAR); mc.searchstr, PROMPT_ECHAR);
mc.width = font_width(sc, mc.dispstr, strlen(mc.dispstr)); mc.width = font_width(sc, mc.dispstr, strlen(mc.dispstr));
mc.hasprompt = 1; mc.hasprompt = 1;
} }
if (initial != NULL) if (initial != NULL)
(void)strlcpy(mc.searchstr, initial, sizeof(mc.searchstr)); strlcpy(mc.searchstr, initial, sizeof(mc.searchstr));
else else
mc.searchstr[0] = '\0'; mc.searchstr[0] = '\0';
@@ -145,7 +124,7 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, char *prompt,
XSelectInput(X_Dpy, sc->menuwin, evmask); XSelectInput(X_Dpy, sc->menuwin, evmask);
XMapRaised(X_Dpy, sc->menuwin); XMapRaised(X_Dpy, sc->menuwin);
if (xu_ptr_grab(sc->menuwin, MENUGRABMASK, Cursor_question) < 0) { if (xu_ptr_grab(sc->menuwin, MenuGrabMask, Cursor_question) < 0) {
XUnmapWindow(X_Dpy, sc->menuwin); XUnmapWindow(X_Dpy, sc->menuwin);
return (NULL); return (NULL);
} }
@@ -163,6 +142,8 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, char *prompt,
XWindowEvent(X_Dpy, sc->menuwin, evmask, &e); XWindowEvent(X_Dpy, sc->menuwin, evmask, &e);
switch (e.type) { switch (e.type) {
default:
break;
case KeyPress: case KeyPress:
if ((mi = menu_handle_key(&e, &mc, menuq, &resultq)) if ((mi = menu_handle_key(&e, &mc, menuq, &resultq))
!= NULL) != NULL)
@@ -179,23 +160,16 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, char *prompt,
!= NULL) != NULL)
goto out; goto out;
break; break;
default:
break;
} }
} }
out: out:
if (dummy == 0 && mi->dummy) { /* no mouse based match */ if (dummy == 0 && mi->dummy) { /* no match */
xfree(mi); xfree (mi);
mi = NULL; mi = NULL;
xu_ptr_ungrab();
XSetInputFocus(X_Dpy, focuswin, focusrevert, CurrentTime);
} }
XSetInputFocus(X_Dpy, focuswin, focusrevert, CurrentTime);
/* restore if user didn't move */
xu_ptr_getpos(sc->rootwin, &xcur, &ycur);
if (xcur == mc.x && ycur == mc.y)
xu_ptr_setpos(sc->rootwin, xsave, ysave);
xu_ptr_ungrab();
XUnmapWindow(X_Dpy, sc->menuwin); XUnmapWindow(X_Dpy, sc->menuwin);
XUngrabKeyboard(X_Dpy, CurrentTime); XUngrabKeyboard(X_Dpy, CurrentTime);
@@ -211,7 +185,8 @@ menu_handle_key(XEvent *e, struct menu_ctx *mc, struct menu_q *menuq,
char chr; char chr;
size_t len; size_t len;
if (menu_keycode(e->xkey.keycode, e->xkey.state, &ctl, &chr) < 0) if (input_keycodetrans(e->xkey.keycode, e->xkey.state,
&ctl, &chr) < 0)
return (NULL); return (NULL);
switch (ctl) { switch (ctl) {
@@ -273,7 +248,7 @@ menu_handle_key(XEvent *e, struct menu_ctx *mc, struct menu_q *menuq,
str[0] = chr; str[0] = chr;
str[1] = '\0'; str[1] = '\0';
mc->changed = 1; mc->changed = 1;
(void)strlcat(mc->searchstr, str, sizeof(mc->searchstr)); strlcat(mc->searchstr, str, sizeof(mc->searchstr));
} }
mc->noresult = 0; mc->noresult = 0;
@@ -296,10 +271,8 @@ static void
menu_draw(struct screen_ctx *sc, struct menu_ctx *mc, struct menu_q *menuq, menu_draw(struct screen_ctx *sc, struct menu_ctx *mc, struct menu_q *menuq,
struct menu_q *resultq) struct menu_q *resultq)
{ {
struct menu *mi; struct menu *mi;
XineramaScreenInfo *xine; int n, dy, xsave, ysave;
int xmin, xmax, ymin, ymax;
int n, dy, xsave, ysave;
if (mc->list) { if (mc->list) {
if (TAILQ_EMPTY(resultq) && mc->list) { if (TAILQ_EMPTY(resultq) && mc->list) {
@@ -317,7 +290,7 @@ menu_draw(struct screen_ctx *sc, struct menu_ctx *mc, struct menu_q *menuq,
mc->width = 0; mc->width = 0;
dy = 0; dy = 0;
if (mc->hasprompt) { if (mc->hasprompt) {
(void)snprintf(mc->dispstr, sizeof(mc->dispstr), "%s%s%s", snprintf(mc->dispstr, sizeof(mc->dispstr), "%s%s%c",
mc->promptstr, mc->searchstr, PROMPT_ECHAR); mc->promptstr, mc->searchstr, PROMPT_ECHAR);
mc->width = font_width(sc, mc->dispstr, strlen(mc->dispstr)); mc->width = font_width(sc, mc->dispstr, strlen(mc->dispstr));
dy = font_height(sc); dy = font_height(sc);
@@ -341,33 +314,18 @@ menu_draw(struct screen_ctx *sc, struct menu_ctx *mc, struct menu_q *menuq,
mc->num++; mc->num++;
} }
xine = screen_find_xinerama(sc, mc->x, mc->y);
if (xine) {
xmin = xine->x_org;
xmax = xine->x_org + xine->width;
ymin = xine->y_org;
ymax = xine->y_org + xine->height;
} else {
xmin = ymin = 0;
xmax = sc->xmax;
ymax = sc->ymax;
}
xsave = mc->x; xsave = mc->x;
ysave = mc->y; ysave = mc->y;
if (mc->x < 0)
mc->x = 0;
else if (mc->x + mc->width >= sc->xmax)
mc->x = sc->xmax - mc->width;
if (mc->x < xmin) if (mc->y + dy >= sc->ymax)
mc->x = xmin; mc->y = sc->ymax - dy;
else if (mc->x + mc->width >= xmax)
mc->x = xmax - mc->width;
if (mc->y + dy >= ymax)
mc->y = ymax - dy;
/* never hide the top of the menu */ /* never hide the top of the menu */
if (mc->y < ymin) { if (mc->y < 0)
mc->y = ymin; mc->y = 0;
dy = ymax - ymin;
}
if (mc->x != xsave || mc->y != ysave) if (mc->x != xsave || mc->y != ysave)
xu_ptr_setpos(sc->rootwin, mc->x, mc->y); xu_ptr_setpos(sc->rootwin, mc->x, mc->y);
@@ -391,7 +349,7 @@ menu_draw(struct screen_ctx *sc, struct menu_ctx *mc, struct menu_q *menuq,
n++; n++;
} }
if (mc->hasprompt && n > 1 && (mc->searchstr[0] != '\0')) if (mc->hasprompt && n > 1)
XFillRectangle(X_Dpy, sc->menuwin, sc->gc, XFillRectangle(X_Dpy, sc->menuwin, sc->gc,
0, font_height(sc), mc->width, font_height(sc)); 0, font_height(sc), mc->width, font_height(sc));
@@ -410,11 +368,11 @@ menu_handle_move(XEvent *e, struct menu_ctx *mc, struct screen_ctx *sc)
XFillRectangle(X_Dpy, sc->menuwin, sc->gc, 0, XFillRectangle(X_Dpy, sc->menuwin, sc->gc, 0,
font_height(sc) * mc->prev, mc->width, font_height(sc)); font_height(sc) * mc->prev, mc->width, font_height(sc));
if (mc->entry != -1) { if (mc->entry != -1) {
(void)xu_ptr_regrab(MENUGRABMASK, Cursor_normal); xu_ptr_regrab(MenuGrabMask, Cursor_select);
XFillRectangle(X_Dpy, sc->menuwin, sc->gc, 0, XFillRectangle(X_Dpy, sc->menuwin, sc->gc, 0,
font_height(sc) * mc->entry, mc->width, font_height(sc)); font_height(sc) * mc->entry, mc->width, font_height(sc));
} else } else
(void)xu_ptr_regrab(MENUGRABMASK, Cursor_default); xu_ptr_regrab(MenuGrabMask, Cursor_default);
} }
static struct menu * static struct menu *
@@ -425,6 +383,7 @@ menu_handle_release(XEvent *e, struct menu_ctx *mc, struct screen_ctx *sc,
int entry, i = 0; int entry, i = 0;
entry = menu_calc_entry(sc, mc, e->xbutton.x, e->xbutton.y); entry = menu_calc_entry(sc, mc, e->xbutton.x, e->xbutton.y);
xu_ptr_ungrab();
if (mc->hasprompt) if (mc->hasprompt)
i = 1; i = 1;
@@ -457,89 +416,3 @@ menu_calc_entry(struct screen_ctx *sc, struct menu_ctx *mc, int x, int y)
return (entry); return (entry);
} }
static int
menu_keycode(KeyCode kc, u_int state, enum ctltype *ctl, char *chr)
{
int ks;
*ctl = CTL_NONE;
*chr = '\0';
ks = XKeycodeToKeysym(X_Dpy, kc, (state & ShiftMask) ? 1 : 0);
/* Look for control characters. */
switch (ks) {
case XK_BackSpace:
*ctl = CTL_ERASEONE;
break;
case XK_Return:
*ctl = CTL_RETURN;
break;
case XK_Up:
*ctl = CTL_UP;
break;
case XK_Down:
*ctl = CTL_DOWN;
break;
case XK_Escape:
*ctl = CTL_ABORT;
break;
}
if (*ctl == CTL_NONE && (state & ControlMask)) {
switch (ks) {
case XK_s:
case XK_S:
/* Emacs "next" */
*ctl = CTL_DOWN;
break;
case XK_r:
case XK_R:
/* Emacs "previous" */
*ctl = CTL_UP;
break;
case XK_u:
case XK_U:
*ctl = CTL_WIPE;
break;
case XK_h:
case XK_H:
*ctl = CTL_ERASEONE;
break;
case XK_a:
case XK_A:
*ctl = CTL_ALL;
break;
}
}
if (*ctl == CTL_NONE && (state & Mod1Mask)) {
switch (ks) {
case XK_j:
case XK_J:
/* Vi "down" */
*ctl = CTL_DOWN;
break;
case XK_k:
case XK_K:
/* Vi "up" */
*ctl = CTL_UP;
break;
}
}
if (*ctl != CTL_NONE)
return (0);
/*
* For regular characters, only (part of, actually) Latin 1
* for now.
*/
if (ks < 0x20 || ks > 0x07e)
return (-1);
*chr = (char)ks;
return (0);
}

View File

@@ -1,8 +1,8 @@
/* /*
* calmwm - the calm window manager * calmwm - the calm window manager
* *
* Copyright (c) 2004 Marius Aamodt Eriksen <marius@monkey.org> * Copyright (c) 2004 Marius Aamodt Eriksen <marius@monkey.org>
* Copyright (c) 2008 rivo nurges <rix@estpak.ee> * Copyright (c) 2008 rivo nurges <rix@estpak.ee>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -16,7 +16,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $OpenBSD$ * $Id$
*/ */
#include <sys/param.h> #include <sys/param.h>
@@ -55,47 +55,46 @@ mousefunc_sweep_draw(struct client_ctx *cc)
{ {
struct screen_ctx *sc = cc->sc; struct screen_ctx *sc = cc->sc;
char asize[10]; /* fits "nnnnxnnnn\0" */ char asize[10]; /* fits "nnnnxnnnn\0" */
int width, width_size, width_name; int width, height, width_size, width_name;
(void)snprintf(asize, sizeof(asize), "%dx%d", snprintf(asize, sizeof(asize), "%dx%d",
(cc->geom.width - cc->hint.basew) / cc->hint.incw, (cc->geom.width - cc->geom.basew) / cc->geom.incw,
(cc->geom.height - cc->hint.baseh) / cc->hint.inch); (cc->geom.height - cc->geom.baseh) / cc->geom.inch);
width_size = font_width(sc, asize, strlen(asize)) + 4; width_size = font_width(sc, asize, strlen(asize)) + 4;
width_name = font_width(sc, cc->name, strlen(cc->name)) + 4; width_name = font_width(sc, cc->name, strlen(cc->name)) + 4;
width = MAX(width_size, width_name); width = MAX(width_size, width_name);
height = font_ascent(sc) + font_descent(sc) + 1;
XReparentWindow(X_Dpy, sc->menuwin, cc->win, 0, 0); XMoveResizeWindow(X_Dpy, sc->menuwin, cc->geom.x, cc->geom.y,
XMoveResizeWindow(X_Dpy, sc->menuwin, 0, 0, width, font_height(sc) * 2); width, height * 2);
XMapWindow(X_Dpy, sc->menuwin); XMapWindow(X_Dpy, sc->menuwin);
XReparentWindow(X_Dpy, sc->menuwin, cc->win, 0, 0);
XClearWindow(X_Dpy, sc->menuwin); XClearWindow(X_Dpy, sc->menuwin);
font_draw(sc, cc->name, strlen(cc->name), sc->menuwin, font_draw(sc, cc->name, strlen(cc->name), sc->menuwin,
2, font_ascent(sc) + 1); 2, font_ascent(sc) + 1);
font_draw(sc, asize, strlen(asize), sc->menuwin, font_draw(sc, asize, strlen(asize), sc->menuwin,
width / 2 - width_size / 2, font_height(sc) + font_ascent(sc) + 1); width / 2 - width_size / 2, height + font_ascent(sc) + 1);
} }
void void
mousefunc_window_resize(struct client_ctx *cc, void *arg) mousefunc_window_resize(struct client_ctx *cc, void *arg)
{ {
XEvent ev; XEvent ev;
Time ltime = 0; Time time = 0;
struct screen_ctx *sc = cc->sc; struct screen_ctx *sc = cc->sc;
int x = cc->geom.x, y = cc->geom.y; int x = cc->geom.x, y = cc->geom.y;
if (cc->flags & CLIENT_FREEZE)
return;
client_raise(cc); client_raise(cc);
client_ptrsave(cc); client_ptrsave(cc);
if (xu_ptr_grab(cc->win, MOUSEMASK, Cursor_resize) < 0) if (xu_ptr_grab(cc->win, MouseMask, Cursor_resize) < 0)
return; return;
xu_ptr_setpos(cc->win, cc->geom.width, cc->geom.height); xu_ptr_setpos(cc->win, cc->geom.width, cc->geom.height);
mousefunc_sweep_draw(cc); mousefunc_sweep_draw(cc);
for (;;) { for (;;) {
XMaskEvent(X_Dpy, MOUSEMASK|ExposureMask, &ev); XMaskEvent(X_Dpy, MouseMask|ExposureMask, &ev);
switch (ev.type) { switch (ev.type) {
case Expose: case Expose:
@@ -107,15 +106,18 @@ mousefunc_window_resize(struct client_ctx *cc, void *arg)
/* Recompute window output */ /* Recompute window output */
mousefunc_sweep_draw(cc); mousefunc_sweep_draw(cc);
/* don't resize more than 60 times / second */ /* don't sync more than 60 times / second */
if ((ev.xmotion.time - ltime) > (1000 / 60)) { if ((ev.xmotion.time - time) > (1000 / 60)) {
ltime = ev.xmotion.time; time = ev.xmotion.time;
XSync(X_Dpy, False);
client_resize(cc); client_resize(cc);
} }
break; break;
case ButtonRelease: case ButtonRelease:
if (ltime) if (time) {
XSync(X_Dpy, False);
client_resize(cc); client_resize(cc);
}
XUnmapWindow(X_Dpy, sc->menuwin); XUnmapWindow(X_Dpy, sc->menuwin);
XReparentWindow(X_Dpy, sc->menuwin, sc->rootwin, 0, 0); XReparentWindow(X_Dpy, sc->menuwin, sc->rootwin, 0, 0);
xu_ptr_ungrab(); xu_ptr_ungrab();
@@ -126,6 +128,7 @@ mousefunc_window_resize(struct client_ctx *cc, void *arg)
if (cc->ptr.y > cc->geom.height) if (cc->ptr.y > cc->geom.height)
cc->ptr.y = cc->geom.height - cc->bwidth; cc->ptr.y = cc->geom.height - cc->bwidth;
client_ptrwarp(cc); client_ptrwarp(cc);
return; return;
} }
} }
@@ -136,46 +139,39 @@ void
mousefunc_window_move(struct client_ctx *cc, void *arg) mousefunc_window_move(struct client_ctx *cc, void *arg)
{ {
XEvent ev; XEvent ev;
Time ltime = 0; Time time = 0;
int px, py; int px, py;
client_raise(cc); client_raise(cc);
if (cc->flags & CLIENT_FREEZE) if (xu_ptr_grab(cc->win, MouseMask, Cursor_move) < 0)
return;
if (xu_ptr_grab(cc->win, MOUSEMASK, Cursor_move) < 0)
return; return;
xu_ptr_getpos(cc->win, &px, &py); xu_ptr_getpos(cc->win, &px, &py);
for (;;) { for (;;) {
XMaskEvent(X_Dpy, MOUSEMASK|ExposureMask, &ev); XMaskEvent(X_Dpy, MouseMask|ExposureMask, &ev);
switch (ev.type) { switch (ev.type) {
case Expose: case Expose:
client_draw_border(cc); client_draw_border(cc);
break; break;
case MotionNotify: case MotionNotify:
cc->geom.x = ev.xmotion.x_root - px - cc->bwidth; cc->geom.x = ev.xmotion.x_root - px;
cc->geom.y = ev.xmotion.y_root - py - cc->bwidth; cc->geom.y = ev.xmotion.y_root - py;
cc->geom.x += client_snapcalc(cc->geom.x, /* don't sync more than 60 times / second */
cc->geom.width, cc->sc->xmax, if ((ev.xmotion.time - time) > (1000 / 60)) {
cc->bwidth, Conf.snapdist); time = ev.xmotion.time;
cc->geom.y += client_snapcalc(cc->geom.y, XSync(X_Dpy, False);
cc->geom.height, cc->sc->ymax,
cc->bwidth, Conf.snapdist);
/* don't move more than 60 times / second */
if ((ev.xmotion.time - ltime) > (1000 / 60)) {
ltime = ev.xmotion.time;
client_move(cc); client_move(cc);
} }
break; break;
case ButtonRelease: case ButtonRelease:
if (ltime) if (time) {
XSync(X_Dpy, False);
client_move(cc); client_move(cc);
}
xu_ptr_ungrab(); xu_ptr_ungrab();
return; return;
} }
@@ -196,12 +192,6 @@ mousefunc_window_lower(struct client_ctx *cc, void *arg)
client_lower(cc); client_lower(cc);
} }
void
mousefunc_window_raise(struct client_ctx *cc, void *arg)
{
client_raise(cc);
}
void void
mousefunc_window_hide(struct client_ctx *cc, void *arg) mousefunc_window_hide(struct client_ctx *cc, void *arg)
{ {
@@ -234,7 +224,7 @@ mousefunc_menu_unhide(struct client_ctx *cc, void *arg)
continue; continue;
mi = xcalloc(1, sizeof(*mi)); mi = xcalloc(1, sizeof(*mi));
(void)strlcpy(mi->text, wname, sizeof(mi->text)); strlcpy(mi->text, wname, sizeof(mi->text));
mi->ctx = cc; mi->ctx = cc;
TAILQ_INSERT_TAIL(&menuq, mi, entry); TAILQ_INSERT_TAIL(&menuq, mi, entry);
} }
@@ -271,7 +261,7 @@ mousefunc_menu_cmd(struct client_ctx *cc, void *arg)
TAILQ_INIT(&menuq); TAILQ_INIT(&menuq);
TAILQ_FOREACH(cmd, &Conf.cmdq, entry) { TAILQ_FOREACH(cmd, &Conf.cmdq, entry) {
mi = xcalloc(1, sizeof(*mi)); mi = xcalloc(1, sizeof(*mi));
(void)strlcpy(mi->text, cmd->label, sizeof(mi->text)); strlcpy(mi->text, cmd->label, sizeof(mi->text));
mi->ctx = cmd; mi->ctx = cmd;
TAILQ_INSERT_TAIL(&menuq, mi, entry); TAILQ_INSERT_TAIL(&menuq, mi, entry);
} }

43
parse.y
View File

@@ -70,10 +70,9 @@ typedef struct {
%token FONTNAME STICKY GAP MOUSEBIND %token FONTNAME STICKY GAP MOUSEBIND
%token AUTOGROUP BIND COMMAND IGNORE %token AUTOGROUP BIND COMMAND IGNORE
%token YES NO BORDERWIDTH MOVEAMOUNT %token YES NO BORDERWIDTH MOVEAMOUNT
%token COLOR SNAPDIST %token COLOR
%token ACTIVEBORDER INACTIVEBORDER %token ACTIVEBORDER INACTIVEBORDER
%token GROUPBORDER UNGROUPBORDER %token GROUPBORDER UNGROUPBORDER
%token MENUBG MENUFG FONTCOLOR
%token ERROR %token ERROR
%token <v.string> STRING %token <v.string> STRING
%token <v.number> NUMBER %token <v.number> NUMBER
@@ -106,8 +105,8 @@ yesno : YES { $$ = 1; }
; ;
main : FONTNAME STRING { main : FONTNAME STRING {
free(conf->font); free(conf->DefaultFontName);
conf->font = $2; conf->DefaultFontName = $2;
} }
| STICKY yesno { | STICKY yesno {
if ($2 == 0) if ($2 == 0)
@@ -121,9 +120,6 @@ main : FONTNAME STRING {
| MOVEAMOUNT NUMBER { | MOVEAMOUNT NUMBER {
conf->mamount = $2; conf->mamount = $2;
} }
| SNAPDIST NUMBER {
conf->snapdist = $2;
}
| COMMAND STRING string { | COMMAND STRING string {
conf_cmd_add(conf, $3, $2, 0); conf_cmd_add(conf, $3, $2, 0);
free($2); free($2);
@@ -143,7 +139,7 @@ main : FONTNAME STRING {
struct winmatch *wm; struct winmatch *wm;
wm = xcalloc(1, sizeof(*wm)); wm = xcalloc(1, sizeof(*wm));
(void)strlcpy(wm->title, $2, sizeof(wm->title)); strlcpy(wm->title, $2, sizeof(wm->title));
TAILQ_INSERT_TAIL(&conf->ignoreq, wm, entry); TAILQ_INSERT_TAIL(&conf->ignoreq, wm, entry);
free($2); free($2);
@@ -170,8 +166,8 @@ color : COLOR colors
; ;
colors : ACTIVEBORDER STRING { colors : ACTIVEBORDER STRING {
free(conf->color[CWM_COLOR_BORDER_ACTIVE].name); free(conf->color[CWM_COLOR_BORDOR_ACTIVE].name);
conf->color[CWM_COLOR_BORDER_ACTIVE].name = $2; conf->color[CWM_COLOR_BORDOR_ACTIVE].name = $2;
} }
| INACTIVEBORDER STRING { | INACTIVEBORDER STRING {
free(conf->color[CWM_COLOR_BORDER_INACTIVE].name); free(conf->color[CWM_COLOR_BORDER_INACTIVE].name);
@@ -185,18 +181,6 @@ colors : ACTIVEBORDER STRING {
free(conf->color[CWM_COLOR_BORDER_UNGROUP].name); free(conf->color[CWM_COLOR_BORDER_UNGROUP].name);
conf->color[CWM_COLOR_BORDER_UNGROUP].name = $2; conf->color[CWM_COLOR_BORDER_UNGROUP].name = $2;
} }
| MENUBG STRING {
free(conf->color[CWM_COLOR_BG_MENU].name);
conf->color[CWM_COLOR_BG_MENU].name = $2;
}
| MENUFG STRING {
free(conf->color[CWM_COLOR_FG_MENU].name);
conf->color[CWM_COLOR_FG_MENU].name = $2;
}
| FONTCOLOR STRING {
free(conf->color[CWM_COLOR_FONT].name);
conf->color[CWM_COLOR_FONT].name = $2;
}
; ;
%% %%
@@ -236,18 +220,14 @@ lookup(char *s)
{ "borderwidth", BORDERWIDTH}, { "borderwidth", BORDERWIDTH},
{ "color", COLOR}, { "color", COLOR},
{ "command", COMMAND}, { "command", COMMAND},
{ "font", FONTCOLOR},
{ "fontname", FONTNAME}, { "fontname", FONTNAME},
{ "gap", GAP}, { "gap", GAP},
{ "groupborder", GROUPBORDER}, { "groupborder", GROUPBORDER},
{ "ignore", IGNORE}, { "ignore", IGNORE},
{ "inactiveborder", INACTIVEBORDER}, { "inactiveborder", INACTIVEBORDER},
{ "menubg", MENUBG},
{ "menufg", MENUFG},
{ "mousebind", MOUSEBIND}, { "mousebind", MOUSEBIND},
{ "moveamount", MOVEAMOUNT}, { "moveamount", MOVEAMOUNT},
{ "no", NO}, { "no", NO},
{ "snapdist", SNAPDIST},
{ "sticky", STICKY}, { "sticky", STICKY},
{ "ungroupborder", UNGROUPBORDER}, { "ungroupborder", UNGROUPBORDER},
{ "yes", YES} { "yes", YES}
@@ -478,6 +458,8 @@ pushfile(const char *name)
nfile->name = xstrdup(name); nfile->name = xstrdup(name);
if ((nfile->stream = fopen(nfile->name, "r")) == NULL) { if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
if (errno != ENOENT)
warn("%s", nfile->name);
free(nfile->name); free(nfile->name);
free(nfile); free(nfile);
return (NULL); return (NULL);
@@ -516,7 +498,7 @@ parse_config(const char *filename, struct conf *xconf)
return (-1); return (-1);
} }
(void)strlcpy(conf->conf_path, filename, sizeof(conf->conf_path)); strlcpy(conf->conf_path, filename, sizeof(conf->conf_path));
conf_init(conf); conf_init(conf);
@@ -541,7 +523,6 @@ parse_config(const char *filename, struct conf *xconf)
xconf->flags = conf->flags; xconf->flags = conf->flags;
xconf->bwidth = conf->bwidth; xconf->bwidth = conf->bwidth;
xconf->mamount = conf->mamount; xconf->mamount = conf->mamount;
xconf->snapdist = conf->snapdist;
xconf->gap = conf->gap; xconf->gap = conf->gap;
while ((cmd = TAILQ_FIRST(&conf->cmdq)) != NULL) { while ((cmd = TAILQ_FIRST(&conf->cmdq)) != NULL) {
@@ -569,15 +550,15 @@ parse_config(const char *filename, struct conf *xconf)
TAILQ_INSERT_TAIL(&xconf->mousebindingq, mb, entry); TAILQ_INSERT_TAIL(&xconf->mousebindingq, mb, entry);
} }
(void)strlcpy(xconf->termpath, conf->termpath, strlcpy(xconf->termpath, conf->termpath,
sizeof(xconf->termpath)); sizeof(xconf->termpath));
(void)strlcpy(xconf->lockpath, conf->lockpath, strlcpy(xconf->lockpath, conf->lockpath,
sizeof(xconf->lockpath)); sizeof(xconf->lockpath));
for (i = 0; i < CWM_COLOR_MAX; i++) for (i = 0; i < CWM_COLOR_MAX; i++)
xconf->color[i].name = conf->color[i].name; xconf->color[i].name = conf->color[i].name;
xconf->font = conf->font; xconf->DefaultFontName = conf->DefaultFontName;
} }
free(conf); free(conf);

View File

@@ -15,7 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $OpenBSD$ * $Id$
*/ */
#include <sys/param.h> #include <sys/param.h>
@@ -101,8 +101,8 @@ screen_find_xinerama(struct screen_ctx *sc, int x, int y)
for (i = 0; i < sc->xinerama_no; i++) { for (i = 0; i < sc->xinerama_no; i++) {
info = &sc->xinerama[i]; info = &sc->xinerama[i];
if (x >= info->x_org && x < info->x_org + info->width && if (x > info->x_org && x < info->x_org + info->width &&
y >= info->y_org && y < info->y_org + info->height) y > info->y_org && y < info->y_org + info->height)
return (info); return (info);
} }
return (NULL); return (NULL);

View File

@@ -2,7 +2,6 @@
* calmwm - the calm window manager * calmwm - the calm window manager
* *
* Copyright (c) 2004 Marius Aamodt Eriksen <marius@monkey.org> * Copyright (c) 2004 Marius Aamodt Eriksen <marius@monkey.org>
*
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies. * copyright notice and this permission notice appear in all copies.
@@ -15,7 +14,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $OpenBSD$ * $Id$
*/ */
#include <sys/param.h> #include <sys/param.h>
@@ -43,10 +42,13 @@ search_match_client(struct menu_q *menuq, struct menu_q *resultq, char *search)
{ {
struct winname *wn; struct winname *wn;
struct menu *mi, *tierp[4], *before = NULL; struct menu *mi, *tierp[4], *before = NULL;
int ntiers;
ntiers = sizeof(tierp) / sizeof(tierp[0]);
TAILQ_INIT(resultq); TAILQ_INIT(resultq);
(void)memset(tierp, 0, sizeof(tierp)); memset(tierp, 0, sizeof(tierp));
/* /*
* In order of rank: * In order of rank:
@@ -90,14 +92,14 @@ search_match_client(struct menu_q *menuq, struct menu_q *resultq, char *search)
* window. Furthermore, this is denoted by a "!" when * window. Furthermore, this is denoted by a "!" when
* printing the window name in the search menu. * printing the window name in the search menu.
*/ */
if (cc == client_current() && tier < nitems(tierp) - 1) if (cc == client_current() && tier < ntiers - 1)
tier++; tier++;
/* Clients that are hidden get ranked one up. */ /* Clients that are hidden get ranked one up. */
if (cc->flags & CLIENT_HIDDEN && tier > 0) if (cc->flags & CLIENT_HIDDEN && tier > 0)
tier--; tier--;
assert(tier < nitems(tierp)); assert(tier < ntiers);
/* /*
* If you have a tierp, insert after it, and make it * If you have a tierp, insert after it, and make it
@@ -134,8 +136,7 @@ search_print_client(struct menu *mi, int list)
if (list) if (list)
cc->matchname = cc->name; cc->matchname = cc->name;
(void)snprintf(mi->print, sizeof(mi->print), "%c%s", flag, snprintf(mi->print, sizeof(mi->print), "%c%s", flag, cc->matchname);
cc->matchname);
if (!list && cc->matchname != cc->name && if (!list && cc->matchname != cc->name &&
strlen(mi->print) < sizeof(mi->print) - 1) { strlen(mi->print) < sizeof(mi->print) - 1) {
@@ -155,8 +156,8 @@ search_print_client(struct menu *mi, int list)
diff = strlen(cc->name); diff = strlen(cc->name);
} }
(void)strlcpy(buf, mi->print, sizeof(buf)); strlcpy(buf, mi->print, sizeof(buf));
(void)snprintf(mi->print, sizeof(mi->print), snprintf(mi->print, sizeof(mi->print),
"%s:%.*s%s", buf, diff, cc->name, marker); "%s:%.*s%s", buf, diff, cc->name, marker);
} }
} }

11
util.c
View File

@@ -15,7 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $OpenBSD$ * $Id$
*/ */
#include <sys/param.h> #include <sys/param.h>
@@ -32,7 +32,7 @@
#define MAXARGLEN 20 #define MAXARGLEN 20
void int
u_spawn(char *argstr) u_spawn(char *argstr)
{ {
switch (fork()) { switch (fork()) {
@@ -42,9 +42,12 @@ u_spawn(char *argstr)
break; break;
case -1: case -1:
warn("fork"); warn("fork");
return (-1);
default: default:
break; break;
} }
return (0);
} }
void void
@@ -76,6 +79,6 @@ u_exec(char *argstr)
} }
*ap = NULL; *ap = NULL;
(void)setsid(); setsid();
(void)execvp(args[0], args); execvp(args[0], args);
} }

View File

@@ -15,7 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $OpenBSD$ * $Id$
*/ */
/* /*
@@ -77,6 +77,7 @@ xev_handle_maprequest(XEvent *ee)
XMapRequestEvent *e = &ee->xmaprequest; XMapRequestEvent *e = &ee->xmaprequest;
struct client_ctx *cc = NULL, *old_cc; struct client_ctx *cc = NULL, *old_cc;
XWindowAttributes xattr; XWindowAttributes xattr;
struct winmatch *wm;
if ((old_cc = client_current()) != NULL) if ((old_cc = client_current()) != NULL)
client_ptrsave(old_cc); client_ptrsave(old_cc);
@@ -86,8 +87,12 @@ xev_handle_maprequest(XEvent *ee)
cc = client_new(e->window, screen_fromroot(xattr.root), 1); cc = client_new(e->window, screen_fromroot(xattr.root), 1);
} }
if ((cc->flags & CLIENT_IGNORE) == 0) TAILQ_FOREACH(wm, &Conf.ignoreq, entry) {
client_ptrwarp(cc); if (strncasecmp(wm->title, cc->name, strlen(wm->title)) == 0)
return;
}
client_ptrwarp(cc);
} }
static void static void
@@ -162,7 +167,7 @@ xev_handle_configurerequest(XEvent *ee)
wc.border_width = cc->bwidth; wc.border_width = cc->bwidth;
XConfigureWindow(X_Dpy, cc->win, e->value_mask, &wc); XConfigureWindow(X_Dpy, cc->win, e->value_mask, &wc);
xu_configure(cc); xev_reconfig(cc);
} else { } else {
/* let it do what it wants, it'll be ours when we map it. */ /* let it do what it wants, it'll be ours when we map it. */
wc.x = e->x; wc.x = e->x;
@@ -192,9 +197,6 @@ xev_handle_propertynotify(XEvent *ee)
case XA_WM_NAME: case XA_WM_NAME:
client_setname(cc); client_setname(cc);
break; break;
case XA_WM_TRANSIENT_FOR:
client_transient(cc);
break;
default: default:
/* do nothing */ /* do nothing */
break; break;
@@ -212,6 +214,25 @@ test:
} }
void
xev_reconfig(struct client_ctx *cc)
{
XConfigureEvent ce;
ce.type = ConfigureNotify;
ce.event = cc->win;
ce.window = cc->win;
ce.x = cc->geom.x;
ce.y = cc->geom.y;
ce.width = cc->geom.width;
ce.height = cc->geom.height;
ce.border_width = cc->bwidth;
ce.above = None;
ce.override_redirect = 0;
XSendEvent(X_Dpy, cc->win, False, StructureNotifyMask, (XEvent *)&ce);
}
static void static void
xev_handle_enternotify(XEvent *ee) xev_handle_enternotify(XEvent *ee)
{ {
@@ -409,14 +430,15 @@ xev_handle_expose(XEvent *ee)
client_draw_border(cc); client_draw_border(cc);
} }
volatile sig_atomic_t xev_quit = 0;
volatile sig_atomic_t _xev_quit = 0;
void void
xev_loop(void) xev_loop(void)
{ {
XEvent e; XEvent e;
while (xev_quit == 0) { while (_xev_quit == 0) {
XNextEvent(X_Dpy, &e); XNextEvent(X_Dpy, &e);
if (e.type - Randr_ev == RRScreenChangeNotify) if (e.type - Randr_ev == RRScreenChangeNotify)
xev_handle_randr(&e); xev_handle_randr(&e);

View File

@@ -15,7 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $OpenBSD$ * $Id$
*/ */
#include <sys/param.h> #include <sys/param.h>

33
xutil.c
View File

@@ -15,7 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* $OpenBSD$ * $Id$
*/ */
#include <sys/param.h> #include <sys/param.h>
@@ -57,9 +57,9 @@ void
xu_btn_grab(Window win, int mask, u_int btn) xu_btn_grab(Window win, int mask, u_int btn)
{ {
int i; int i;
for (i = 0; i < nitems(ign_mods); i++) for (i = 0; i < sizeof(ign_mods)/sizeof(*ign_mods); i++)
XGrabButton(X_Dpy, btn, (mask | ign_mods[i]), win, XGrabButton(X_Dpy, btn, (mask | ign_mods[i]), win,
False, BUTTONMASK, GrabModeAsync, False, ButtonMask, GrabModeAsync,
GrabModeSync, None, None); GrabModeSync, None, None);
} }
@@ -67,7 +67,7 @@ void
xu_btn_ungrab(Window win, int mask, u_int btn) xu_btn_ungrab(Window win, int mask, u_int btn)
{ {
int i; int i;
for (i = 0; i < nitems(ign_mods); i++) for (i = 0; i < sizeof(ign_mods)/sizeof(*ign_mods); i++)
XUngrabButton(X_Dpy, btn, (mask | ign_mods[i]), win); XUngrabButton(X_Dpy, btn, (mask | ign_mods[i]), win);
} }
@@ -98,7 +98,7 @@ xu_key_grab(Window win, int mask, int keysym)
(XKeycodeToKeysym(X_Dpy, code, 1) == keysym)) (XKeycodeToKeysym(X_Dpy, code, 1) == keysym))
mask |= ShiftMask; mask |= ShiftMask;
for (i = 0; i < nitems(ign_mods); i++) for (i = 0; i < sizeof(ign_mods)/sizeof(*ign_mods); i++)
XGrabKey(X_Dpy, code, (mask | ign_mods[i]), win, XGrabKey(X_Dpy, code, (mask | ign_mods[i]), win,
True, GrabModeAsync, GrabModeAsync); True, GrabModeAsync, GrabModeAsync);
} }
@@ -114,35 +114,16 @@ xu_key_ungrab(Window win, int mask, int keysym)
(XKeycodeToKeysym(X_Dpy, code, 1) == keysym)) (XKeycodeToKeysym(X_Dpy, code, 1) == keysym))
mask |= ShiftMask; mask |= ShiftMask;
for (i = 0; i < nitems(ign_mods); i++) for (i = 0; i < sizeof(ign_mods)/sizeof(*ign_mods); i++)
XUngrabKey(X_Dpy, code, (mask | ign_mods[i]), win); XUngrabKey(X_Dpy, code, (mask | ign_mods[i]), win);
} }
void
xu_configure(struct client_ctx *cc)
{
XConfigureEvent ce;
ce.type = ConfigureNotify;
ce.event = cc->win;
ce.window = cc->win;
ce.x = cc->geom.x;
ce.y = cc->geom.y;
ce.width = cc->geom.width;
ce.height = cc->geom.height;
ce.border_width = cc->bwidth;
ce.above = None;
ce.override_redirect = 0;
XSendEvent(X_Dpy, cc->win, False, StructureNotifyMask, (XEvent *)&ce);
}
void void
xu_sendmsg(Window win, Atom atm, long val) xu_sendmsg(Window win, Atom atm, long val)
{ {
XEvent e; XEvent e;
(void)memset(&e, 0, sizeof(e)); memset(&e, 0, sizeof(e));
e.xclient.type = ClientMessage; e.xclient.type = ClientMessage;
e.xclient.window = win; e.xclient.window = win;
e.xclient.message_type = atm; e.xclient.message_type = atm;