mirror of
https://github.com/leahneukirchen/cwm.git
synced 2023-08-10 21:13:12 +03:00
Compare commits
42 Commits
OPENBSD_4_
...
OPENBSD_4_
Author | SHA1 | Date | |
---|---|---|---|
![]() |
17ae65adc5 | ||
![]() |
507b65a27f | ||
![]() |
4fe12f528c | ||
![]() |
6ad198022b | ||
![]() |
c750462d13 | ||
![]() |
9203c7e8ca | ||
![]() |
b23cef2e4a | ||
![]() |
01af04a342 | ||
![]() |
7660bf0db0 | ||
![]() |
779177a53d | ||
![]() |
87964e5c7e | ||
![]() |
e239976078 | ||
![]() |
712f3f62c7 | ||
![]() |
e2f3810fe8 | ||
![]() |
1b269199c1 | ||
![]() |
0548673f2f | ||
![]() |
bd4c4d7734 | ||
![]() |
fa87ef4a9e | ||
![]() |
399253a4ff | ||
![]() |
ec8e6052ba | ||
![]() |
5c757cc7f4 | ||
![]() |
49e218cf53 | ||
![]() |
7e110f379b | ||
![]() |
c07123ec78 | ||
![]() |
d1050afb60 | ||
![]() |
dcfae161a2 | ||
![]() |
0aca400461 | ||
![]() |
590169ce24 | ||
![]() |
99afa5091f | ||
![]() |
b47283ab41 | ||
![]() |
b523788c0e | ||
![]() |
ee0ec9a453 | ||
![]() |
d2a54bc115 | ||
![]() |
841c646a2b | ||
![]() |
25af744559 | ||
![]() |
be5dfb4ea4 | ||
![]() |
a0739c6cd4 | ||
![]() |
e2610449d1 | ||
![]() |
2bd5e53c2e | ||
![]() |
60a88f54cc | ||
![]() |
61601991b5 | ||
![]() |
a0082c58a4 |
8
Makefile
8
Makefile
@@ -4,14 +4,16 @@
|
||||
|
||||
PROG= cwm
|
||||
|
||||
SRCS= calmwm.c screen.c xmalloc.c client.c grab.c menu.c \
|
||||
SRCS= calmwm.c screen.c xmalloc.c client.c menu.c \
|
||||
search.c util.c xutil.c conf.c input.c xevents.c group.c \
|
||||
kbfunc.c mousefunc.c font.c parse.y
|
||||
|
||||
CPPFLAGS+= -I${X11BASE}/include -I${X11BASE}/include/freetype2 -I${.CURDIR}
|
||||
|
||||
LDADD+= -L${X11BASE}/lib -lXft -lXrender -lX11 -lXau -lXdmcp -lXext \
|
||||
-lfontconfig -lexpat -lfreetype -lz
|
||||
CFLAGS+= -Wall
|
||||
|
||||
LDADD+= -L${X11BASE}/lib -lXft -lXrender -lX11 -lXau -lXdmcp \
|
||||
-lfontconfig -lexpat -lfreetype -lz -lXinerama -lXrandr -lXext
|
||||
|
||||
MANDIR= ${X11BASE}/man/cat
|
||||
MAN= cwm.1 cwmrc.5
|
||||
|
2
TODO
2
TODO
@@ -16,8 +16,6 @@
|
||||
|
||||
- geographical keyboard navigation (window switching)
|
||||
|
||||
- search should ignore the current window. (not add to match list).
|
||||
|
||||
- make kbd shortcuts/events more general. the ability to associate an
|
||||
event with a mode (i.e. prioritize). gets rid of hacky-ness in
|
||||
groups, etc.
|
||||
|
83
calmwm.c
83
calmwm.c
@@ -31,19 +31,13 @@ Cursor Cursor_question;
|
||||
|
||||
struct screen_ctx_q Screenq;
|
||||
struct screen_ctx *Curscreen;
|
||||
u_int Nscreens;
|
||||
|
||||
struct client_ctx_q Clientq;
|
||||
|
||||
int Doshape, Shape_ev;
|
||||
int HasXinerama, HasRandr, Randr_ev;
|
||||
int Starting;
|
||||
struct conf Conf;
|
||||
|
||||
/* From TWM */
|
||||
#define gray_width 2
|
||||
#define gray_height 2
|
||||
static char gray_bits[] = {0x02, 0x01};
|
||||
|
||||
static void _sigchld_cb(int);
|
||||
static void dpy_init(const char *);
|
||||
|
||||
@@ -69,10 +63,6 @@ main(int argc, char **argv)
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
/* Ignore a few signals. */
|
||||
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
|
||||
err(1, "signal");
|
||||
|
||||
if (signal(SIGCHLD, _sigchld_cb) == SIG_ERR)
|
||||
err(1, "signal");
|
||||
|
||||
@@ -83,10 +73,12 @@ main(int argc, char **argv)
|
||||
bzero(&Conf, sizeof(Conf));
|
||||
conf_setup(&Conf, conf_file);
|
||||
client_setup();
|
||||
xu_getatoms();
|
||||
x_setup();
|
||||
Starting = 0;
|
||||
|
||||
xev_init();
|
||||
|
||||
XEV_QUICK(NULL, NULL, MapRequest, xev_handle_maprequest, NULL);
|
||||
XEV_QUICK(NULL, NULL, UnmapNotify, xev_handle_unmapnotify, NULL);
|
||||
XEV_QUICK(NULL, NULL, ConfigureRequest,
|
||||
@@ -119,7 +111,7 @@ dpy_init(const char *dpyname)
|
||||
|
||||
XSetErrorHandler(x_errorhandler);
|
||||
|
||||
Doshape = XShapeQueryExtension(X_Dpy, &Shape_ev, &i);
|
||||
HasRandr = XRRQueryExtension(X_Dpy, &Randr_ev, &i);
|
||||
|
||||
TAILQ_INIT(&Screenq);
|
||||
}
|
||||
@@ -131,9 +123,8 @@ x_setup(void)
|
||||
struct keybinding *kb;
|
||||
int i;
|
||||
|
||||
Nscreens = ScreenCount(X_Dpy);
|
||||
for (i = 0; i < (int)Nscreens; i++) {
|
||||
XMALLOC(sc, struct screen_ctx);
|
||||
for (i = 0; i < ScreenCount(X_Dpy); i++) {
|
||||
XCALLOC(sc, struct screen_ctx);
|
||||
x_setupscreen(sc, i);
|
||||
TAILQ_INSERT_TAIL(&Screenq, sc, entry);
|
||||
}
|
||||
@@ -145,7 +136,6 @@ x_setup(void)
|
||||
TAILQ_FOREACH(kb, &Conf.keybindingq, entry)
|
||||
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);
|
||||
@@ -161,11 +151,11 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
|
||||
Window *wins, w0, w1;
|
||||
XWindowAttributes winattr;
|
||||
XSetWindowAttributes rootattr;
|
||||
int fake;
|
||||
u_int nwins, i;
|
||||
|
||||
Curscreen = sc;
|
||||
|
||||
sc->display = x_screenname(which);
|
||||
sc->which = which;
|
||||
sc->rootwin = RootWindow(X_Dpy, which);
|
||||
|
||||
@@ -181,7 +171,7 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
|
||||
XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, which),
|
||||
"red", &sc->redcolor, &tmp);
|
||||
XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, which),
|
||||
"#00ccc8", &sc->cyancolor, &tmp);
|
||||
"#666666", &sc->graycolor, &tmp);
|
||||
XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, which),
|
||||
"white", &sc->whitecolor, &tmp);
|
||||
XAllocNamedColor(X_Dpy, DefaultColormap(X_Dpy, which),
|
||||
@@ -191,19 +181,7 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
|
||||
sc->whitepixl = WhitePixel(X_Dpy, sc->which);
|
||||
sc->bluepixl = sc->fccolor.pixel;
|
||||
sc->redpixl = sc->redcolor.pixel;
|
||||
sc->cyanpixl = sc->cyancolor.pixel;
|
||||
|
||||
sc->gray = XCreatePixmapFromBitmapData(X_Dpy, sc->rootwin,
|
||||
gray_bits, gray_width, gray_height,
|
||||
sc->blackpixl, sc->whitepixl, DefaultDepth(X_Dpy, sc->which));
|
||||
|
||||
sc->blue = XCreatePixmapFromBitmapData(X_Dpy, sc->rootwin,
|
||||
gray_bits, gray_width, gray_height,
|
||||
sc->bluepixl, sc->whitepixl, DefaultDepth(X_Dpy, sc->which));
|
||||
|
||||
sc->red = XCreatePixmapFromBitmapData(X_Dpy, sc->rootwin,
|
||||
gray_bits, gray_width, gray_height,
|
||||
sc->redpixl, sc->whitepixl, DefaultDepth(X_Dpy, sc->which));
|
||||
sc->graypixl = sc->graycolor.pixel;
|
||||
|
||||
gv.foreground = sc->blackpixl^sc->whitepixl;
|
||||
gv.background = sc->whitepixl;
|
||||
@@ -229,11 +207,8 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
|
||||
for (i = 0; i < nwins; i++) {
|
||||
XGetWindowAttributes(X_Dpy, wins[i], &winattr);
|
||||
if (winattr.override_redirect ||
|
||||
winattr.map_state != IsViewable) {
|
||||
char *name;
|
||||
XFetchName(X_Dpy, wins[i], &name);
|
||||
winattr.map_state != IsViewable)
|
||||
continue;
|
||||
}
|
||||
client_new(wins[i], sc, winattr.map_state != IsUnmapped);
|
||||
}
|
||||
XFree(wins);
|
||||
@@ -246,37 +221,23 @@ x_setupscreen(struct screen_ctx *sc, u_int which)
|
||||
XChangeWindowAttributes(X_Dpy, sc->rootwin,
|
||||
CWEventMask, &rootattr);
|
||||
|
||||
if (XineramaQueryExtension(X_Dpy, &fake, &fake) == 1 &&
|
||||
((HasXinerama = XineramaIsActive(X_Dpy)) == 1))
|
||||
HasXinerama = 1;
|
||||
if (HasRandr)
|
||||
XRRSelectInput(X_Dpy, sc->rootwin, RRScreenChangeNotifyMask);
|
||||
/*
|
||||
* initial setup of xinerama screens, if we're using RandR then we'll
|
||||
* redo this whenever the screen changes since a CTRC may have been
|
||||
* added or removed
|
||||
*/
|
||||
screen_init_xinerama(sc);
|
||||
|
||||
XSync(X_Dpy, False);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
char *
|
||||
x_screenname(int which)
|
||||
{
|
||||
char *cp, *dstr, *sn;
|
||||
size_t snlen;
|
||||
|
||||
if (which > 9)
|
||||
errx(1, "Can't handle more than 9 screens. If you need it, "
|
||||
"tell <marius@monkey.org>. It's a trivial fix.");
|
||||
|
||||
dstr = xstrdup(DisplayString(X_Dpy));
|
||||
|
||||
if ((cp = strrchr(dstr, ':')) == NULL)
|
||||
return (NULL);
|
||||
|
||||
if ((cp = strchr(cp, '.')) != NULL)
|
||||
*cp = '\0';
|
||||
|
||||
snlen = strlen(dstr) + 3; /* string, dot, number, null */
|
||||
sn = (char *)xmalloc(snlen);
|
||||
snprintf(sn, snlen, "%s.%d", dstr, which);
|
||||
free(dstr);
|
||||
|
||||
return (sn);
|
||||
}
|
||||
|
||||
int
|
||||
x_errorhandler(Display *dpy, XErrorEvent *e)
|
||||
{
|
||||
|
122
calmwm.h
122
calmwm.h
@@ -45,14 +45,11 @@ struct screen_ctx {
|
||||
Window rootwin;
|
||||
Window menuwin;
|
||||
Colormap colormap;
|
||||
XColor bgcolor, fgcolor, fccolor, redcolor, cyancolor,
|
||||
XColor bgcolor, fgcolor, fccolor, redcolor, graycolor,
|
||||
whitecolor, blackcolor;
|
||||
char *display;
|
||||
unsigned long blackpixl, whitepixl, redpixl, bluepixl, cyanpixl;
|
||||
unsigned long blackpixl, whitepixl, redpixl, bluepixl, graypixl;
|
||||
GC gc;
|
||||
|
||||
Pixmap gray, blue, red;
|
||||
|
||||
int altpersist;
|
||||
|
||||
int xmax;
|
||||
@@ -62,6 +59,9 @@ struct screen_ctx {
|
||||
|
||||
XftDraw *xftdraw;
|
||||
XftColor xftcolor;
|
||||
|
||||
int xinerama_no;
|
||||
XineramaScreenInfo *xinerama;
|
||||
};
|
||||
|
||||
TAILQ_HEAD(screen_ctx_q, screen_ctx);
|
||||
@@ -81,7 +81,6 @@ TAILQ_HEAD(screen_ctx_q, screen_ctx);
|
||||
#define CLIENT_HIGHLIGHT_BLUE 1
|
||||
#define CLIENT_HIGHLIGHT_RED 2
|
||||
|
||||
|
||||
struct winname {
|
||||
TAILQ_ENTRY(winname) entry;
|
||||
char *name;
|
||||
@@ -101,8 +100,6 @@ struct client_ctx {
|
||||
|
||||
Colormap cmap;
|
||||
|
||||
Window pwin;
|
||||
|
||||
u_int bwidth;
|
||||
struct {
|
||||
int x, y, width, height;
|
||||
@@ -113,8 +110,6 @@ struct client_ctx {
|
||||
int x,y;
|
||||
} ptr;
|
||||
|
||||
int beepbeep;
|
||||
|
||||
int xproto;
|
||||
|
||||
int flags;
|
||||
@@ -139,15 +134,12 @@ struct client_ctx {
|
||||
|
||||
TAILQ_HEAD(client_ctx_q, client_ctx);
|
||||
|
||||
static char *shortcut_to_name[] = {
|
||||
"nogroup", "one", "two", "three",
|
||||
"four", "five", "six", "seven",
|
||||
"eight", "nine"
|
||||
};
|
||||
extern const char *shortcut_to_name[];
|
||||
|
||||
struct group_ctx {
|
||||
TAILQ_ENTRY(group_ctx) entry;
|
||||
struct client_ctx_q clients;
|
||||
const char *name;
|
||||
int shortcut;
|
||||
int hidden;
|
||||
int nhidden;
|
||||
@@ -213,14 +205,19 @@ TAILQ_HEAD(winmatch_q, winmatch);
|
||||
|
||||
#define KBTOGROUP(X) ((X) - 1)
|
||||
|
||||
union arg {
|
||||
char *c;
|
||||
int i;
|
||||
};
|
||||
|
||||
struct keybinding {
|
||||
TAILQ_ENTRY(keybinding) entry;
|
||||
void (*callback)(struct client_ctx *, union arg *);
|
||||
union arg argument;
|
||||
int modmask;
|
||||
int keysym;
|
||||
int keycode;
|
||||
int flags;
|
||||
void (*callback)(struct client_ctx *, void *);
|
||||
void *argument;
|
||||
TAILQ_ENTRY(keybinding) entry;
|
||||
};
|
||||
|
||||
struct cmd {
|
||||
@@ -257,6 +254,10 @@ struct conf {
|
||||
|
||||
#define CONF_STICKY_GROUPS 0x0001
|
||||
int flags;
|
||||
#define CONF_BWIDTH 1
|
||||
int bwidth;
|
||||
#define CONF_MAMOUNT 1
|
||||
int mamount;
|
||||
|
||||
char termpath[MAXPATHLEN];
|
||||
char lockpath[MAXPATHLEN];
|
||||
@@ -310,16 +311,14 @@ int input_keycodetrans(KeyCode, u_int, enum ctltype *,
|
||||
|
||||
int x_errorhandler(Display *, XErrorEvent *);
|
||||
void x_setup(void);
|
||||
char *x_screenname(int);
|
||||
void x_setupscreen(struct screen_ctx *, u_int);
|
||||
__dead void usage(void);
|
||||
|
||||
struct client_ctx *client_find(Window);
|
||||
void client_setup(void);
|
||||
struct client_ctx *client_new(Window, struct screen_ctx *, int);
|
||||
int client_delete(struct client_ctx *, int, int);
|
||||
int client_delete(struct client_ctx *);
|
||||
void client_setactive(struct client_ctx *, int);
|
||||
void client_gravitate(struct client_ctx *, int);
|
||||
void client_resize(struct client_ctx *);
|
||||
void client_lower(struct client_ctx *);
|
||||
void client_raise(struct client_ctx *);
|
||||
@@ -329,7 +328,6 @@ 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_nocurrent(void);
|
||||
void client_setname(struct client_ctx *);
|
||||
void client_warp(struct client_ctx *);
|
||||
void client_ptrwarp(struct client_ctx *);
|
||||
@@ -339,8 +337,6 @@ void client_update(struct client_ctx *);
|
||||
void client_placecalc(struct client_ctx *);
|
||||
void client_maximize(struct client_ctx *);
|
||||
void client_vertmaximize(struct client_ctx *);
|
||||
u_long client_bg_pixel(struct client_ctx *);
|
||||
Pixmap client_bg_pixmap(struct client_ctx *);
|
||||
void client_map(struct client_ctx *);
|
||||
void client_mtf(struct client_ctx *);
|
||||
struct client_ctx *client_cycle(int);
|
||||
@@ -348,7 +344,6 @@ struct client_ctx *client_mrunext(struct client_ctx *);
|
||||
struct client_ctx *client_mruprev(struct client_ctx *);
|
||||
void client_gethints(struct client_ctx *);
|
||||
void client_freehints(struct client_ctx *);
|
||||
void client_do_shape(struct client_ctx *);
|
||||
|
||||
struct menu *menu_filter(struct menu_q *, char *, char *, int,
|
||||
void (*)(struct menu_q *, struct menu_q *, char *),
|
||||
@@ -368,7 +363,7 @@ void xev_handle_keypress(struct xevent *, XEvent *);
|
||||
void xev_handle_keyrelease(struct xevent *, XEvent *);
|
||||
void xev_handle_expose(struct xevent *, XEvent *);
|
||||
void xev_handle_clientmessage(struct xevent *, XEvent *);
|
||||
void xev_handle_shape(struct xevent *, XEvent *);
|
||||
void xev_handle_randr(struct xevent *, XEvent *);
|
||||
void xev_handle_mapping(struct xevent *, XEvent *);
|
||||
|
||||
#define XEV_QUICK(a, b, c, d, e) do { \
|
||||
@@ -384,6 +379,7 @@ struct xevent *xev_new(Window *, Window *, int,
|
||||
void xev_register(struct xevent *);
|
||||
void xev_loop(void);
|
||||
|
||||
void xu_getatoms(void);
|
||||
int xu_ptr_grab(Window, int, Cursor);
|
||||
void xu_btn_grab(Window, int, u_int);
|
||||
int xu_ptr_regrab(int, Cursor);
|
||||
@@ -403,9 +399,6 @@ int xu_getstate(struct client_ctx *, int *);
|
||||
int u_spawn(char *);
|
||||
void u_exec(char *);
|
||||
|
||||
void grab_sweep(struct client_ctx *);
|
||||
void grab_drag(struct client_ctx *);
|
||||
|
||||
void xfree(void *);
|
||||
void *xmalloc(size_t);
|
||||
void *xcalloc(size_t, size_t);
|
||||
@@ -417,6 +410,8 @@ char *xstrdup(const char *);
|
||||
struct screen_ctx *screen_fromroot(Window);
|
||||
struct screen_ctx *screen_current(void);
|
||||
void screen_updatestackingorder(void);
|
||||
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 *);
|
||||
@@ -429,30 +424,40 @@ void conf_mouseunbind(struct conf *, struct mousebinding *);
|
||||
void conf_grab_mouse(struct client_ctx *);
|
||||
void conf_reload(struct conf *);
|
||||
void conf_font(struct conf *);
|
||||
void conf_init(struct conf *);
|
||||
void conf_clear(struct conf *);
|
||||
void conf_cmd_add(struct conf *, char *, char *, int);
|
||||
|
||||
void kbfunc_client_lower(struct client_ctx *, void *);
|
||||
void kbfunc_client_raise(struct client_ctx *, void *);
|
||||
void kbfunc_client_search(struct client_ctx *, void *);
|
||||
void kbfunc_client_hide(struct client_ctx *, void *);
|
||||
void kbfunc_client_cycle(struct client_ctx *, void *);
|
||||
void kbfunc_client_rcycle(struct client_ctx *, void *);
|
||||
void kbfunc_cmdexec(struct client_ctx *, void *);
|
||||
void kbfunc_client_label(struct client_ctx *, void *);
|
||||
void kbfunc_client_delete(struct client_ctx *, void *);
|
||||
void kbfunc_client_group(struct client_ctx *, void *);
|
||||
void kbfunc_client_cyclegroup(struct client_ctx *, void *);
|
||||
void kbfunc_client_nogroup(struct client_ctx *, void *);
|
||||
void kbfunc_client_grouptoggle(struct client_ctx *, void *);
|
||||
void kbfunc_client_maximize(struct client_ctx *, void *);
|
||||
void kbfunc_client_vmaximize(struct client_ctx *, void *);
|
||||
void kbfunc_reload(struct client_ctx *, void *);
|
||||
void kbfunc_quit_wm(struct client_ctx *, void *);
|
||||
void kbfunc_moveresize(struct client_ctx *, void *);
|
||||
void kbfunc_menu_search(struct client_ctx *, void *);
|
||||
void kbfunc_exec(struct client_ctx *, void *);
|
||||
void kbfunc_ssh(struct client_ctx *, void *);
|
||||
void kbfunc_term(struct client_ctx *, void *);
|
||||
void kbfunc_lock(struct client_ctx *, void *);
|
||||
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_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_maximize(struct client_ctx *,
|
||||
union arg *);
|
||||
void kbfunc_client_vmaximize(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 *);
|
||||
@@ -507,11 +512,20 @@ extern Cursor Cursor_question;
|
||||
|
||||
extern struct screen_ctx_q Screenq;
|
||||
extern struct screen_ctx *curscreen;
|
||||
extern u_int Nscreens;
|
||||
|
||||
extern struct client_ctx_q Clientq;
|
||||
|
||||
extern int Doshape, Shape_ev;
|
||||
extern int HasXinerama, HasRandr, Randr_ev;
|
||||
extern struct conf Conf;
|
||||
|
||||
#define WM_STATE cwm_atoms[0]
|
||||
#define WM_DELETE_WINDOW cwm_atoms[1]
|
||||
#define WM_TAKE_FOCUS cwm_atoms[2]
|
||||
#define WM_PROTOCOLS cwm_atoms[3]
|
||||
#define _MOTIF_WM_HINTS cwm_atoms[4]
|
||||
#define _CWM_GRP cwm_atoms[5]
|
||||
#define CWM_NO_ATOMS 6
|
||||
|
||||
extern Atom cwm_atoms[CWM_NO_ATOMS];
|
||||
|
||||
#endif /* _CALMWM_H_ */
|
||||
|
353
client.c
353
client.c
@@ -21,10 +21,9 @@
|
||||
#include "headers.h"
|
||||
#include "calmwm.h"
|
||||
|
||||
int _inwindowbounds(struct client_ctx *, int, int);
|
||||
static int _client_inbound(struct client_ctx *, int, int);
|
||||
|
||||
static char emptystring[] = "";
|
||||
|
||||
struct client_ctx *_curcc = NULL;
|
||||
|
||||
void
|
||||
@@ -39,7 +38,7 @@ client_find(Window win)
|
||||
struct client_ctx *cc;
|
||||
|
||||
TAILQ_FOREACH(cc, &Clientq, entry)
|
||||
if (cc->pwin == win || cc->win == win)
|
||||
if (cc->win == win)
|
||||
return (cc);
|
||||
|
||||
return (NULL);
|
||||
@@ -49,11 +48,10 @@ struct client_ctx *
|
||||
client_new(Window win, struct screen_ctx *sc, int mapped)
|
||||
{
|
||||
struct client_ctx *cc;
|
||||
XSetWindowAttributes pxattr;
|
||||
XWindowAttributes wattr;
|
||||
XWMHints *wmhints;
|
||||
long tmp;
|
||||
int x, y, height, width, state;
|
||||
int state;
|
||||
|
||||
if (win == None)
|
||||
return (NULL);
|
||||
@@ -66,6 +64,7 @@ client_new(Window win, struct screen_ctx *sc, int mapped)
|
||||
cc->sc = sc;
|
||||
cc->win = win;
|
||||
cc->size = XAllocSizeHints();
|
||||
XGetWMNormalHints(X_Dpy, cc->win, cc->size, &tmp);
|
||||
if (cc->size->width_inc == 0)
|
||||
cc->size->width_inc = 1;
|
||||
if (cc->size->height_inc == 0)
|
||||
@@ -79,7 +78,6 @@ client_new(Window win, struct screen_ctx *sc, int mapped)
|
||||
*/
|
||||
conf_client(cc);
|
||||
|
||||
XGetWMNormalHints(X_Dpy, cc->win, cc->size, &tmp);
|
||||
XGetWindowAttributes(X_Dpy, cc->win, &wattr);
|
||||
|
||||
if (cc->size->flags & PBaseSize) {
|
||||
@@ -94,8 +92,6 @@ client_new(Window win, struct screen_ctx *sc, int mapped)
|
||||
cc->ptr.x = -1;
|
||||
cc->ptr.y = -1;
|
||||
|
||||
client_gravitate(cc, 1);
|
||||
|
||||
cc->geom.x = wattr.x;
|
||||
cc->geom.y = wattr.y;
|
||||
cc->geom.width = wattr.width;
|
||||
@@ -110,7 +106,9 @@ client_new(Window win, struct screen_ctx *sc, int mapped)
|
||||
|
||||
XFree(wmhints);
|
||||
}
|
||||
client_move(cc);
|
||||
}
|
||||
client_draw_border(cc);
|
||||
|
||||
if (xu_getstate(cc, &state) < 0)
|
||||
state = NormalState;
|
||||
@@ -118,41 +116,15 @@ client_new(Window win, struct screen_ctx *sc, int mapped)
|
||||
XSelectInput(X_Dpy, cc->win, ColormapChangeMask | EnterWindowMask |
|
||||
PropertyChangeMask | KeyReleaseMask);
|
||||
|
||||
x = cc->geom.x - cc->bwidth;
|
||||
y = cc->geom.y - cc->bwidth;
|
||||
|
||||
width = cc->geom.width;
|
||||
height = cc->geom.height;
|
||||
if (cc->bwidth > 1) {
|
||||
width += (cc->bwidth)*2;
|
||||
height += (cc->bwidth)*2;
|
||||
}
|
||||
pxattr.override_redirect = True;
|
||||
pxattr.background_pixel = sc->bgcolor.pixel;
|
||||
pxattr.event_mask = ChildMask | ButtonPressMask | ButtonReleaseMask |
|
||||
ExposureMask | EnterWindowMask;
|
||||
|
||||
cc->pwin = XCreateWindow(X_Dpy, sc->rootwin, x, y,
|
||||
width, height, 0, /* XXX */
|
||||
DefaultDepth(X_Dpy, sc->which), CopyFromParent,
|
||||
DefaultVisual(X_Dpy, sc->which),
|
||||
CWOverrideRedirect | CWBackPixel | CWEventMask, &pxattr);
|
||||
|
||||
cc->active = 0;
|
||||
|
||||
XAddToSaveSet(X_Dpy, cc->win);
|
||||
XSetWindowBorderWidth(X_Dpy, cc->win, 0);
|
||||
XReparentWindow(X_Dpy, cc->win, cc->pwin, cc->bwidth, cc->bwidth);
|
||||
|
||||
/* Notify client of its configuration. */
|
||||
xev_reconfig(cc);
|
||||
|
||||
if (state == IconicState)
|
||||
client_hide(cc);
|
||||
else {
|
||||
XMapRaised(X_Dpy, cc->pwin);
|
||||
XMapWindow(X_Dpy, cc->win);
|
||||
}
|
||||
else
|
||||
client_unhide(cc);
|
||||
|
||||
xu_setstate(cc, cc->state);
|
||||
|
||||
@@ -171,51 +143,18 @@ client_new(Window win, struct screen_ctx *sc, int mapped)
|
||||
return (cc);
|
||||
}
|
||||
|
||||
void
|
||||
client_do_shape(struct client_ctx *cc)
|
||||
{
|
||||
/* Windows not rectangular require more effort */
|
||||
XRectangle *r;
|
||||
int n, tmp;
|
||||
|
||||
if (Doshape) {
|
||||
XShapeSelectInput(X_Dpy, cc->win, ShapeNotifyMask);
|
||||
|
||||
r = XShapeGetRectangles(X_Dpy, cc->win, ShapeBounding,
|
||||
&n, &tmp);
|
||||
|
||||
if (n > 1)
|
||||
XShapeCombineShape(X_Dpy, cc->pwin, ShapeBounding,
|
||||
cc->bwidth, cc->bwidth, cc->win, ShapeBounding,
|
||||
ShapeSet);
|
||||
XFree(r);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
client_delete(struct client_ctx *cc, int sendevent, int ignorewindow)
|
||||
client_delete(struct client_ctx *cc)
|
||||
{
|
||||
struct screen_ctx *sc = CCTOSC(cc);
|
||||
struct winname *wn;
|
||||
|
||||
if (cc->state == IconicState && !sendevent)
|
||||
return (1);
|
||||
|
||||
group_client_delete(cc);
|
||||
|
||||
XGrabServer(X_Dpy);
|
||||
xu_setstate(cc, WithdrawnState);
|
||||
XRemoveFromSaveSet(X_Dpy, cc->win);
|
||||
|
||||
if (!ignorewindow) {
|
||||
client_gravitate(cc, 0);
|
||||
XSetWindowBorderWidth(X_Dpy, cc->win, 1); /* XXX */
|
||||
XReparentWindow(X_Dpy, cc->win,
|
||||
sc->rootwin, cc->geom.x, cc->geom.y);
|
||||
}
|
||||
if (cc->pwin)
|
||||
XDestroyWindow(X_Dpy, cc->pwin);
|
||||
|
||||
XSync(X_Dpy, False);
|
||||
XUngrabServer(X_Dpy);
|
||||
|
||||
@@ -296,42 +235,40 @@ client_current(void)
|
||||
return (_curcc);
|
||||
}
|
||||
|
||||
void
|
||||
client_gravitate(struct client_ctx *cc, int yes)
|
||||
{
|
||||
int dx = 0, dy = 0, mult = yes ? 1 : -1;
|
||||
int gravity = (cc->size->flags & PWinGravity) ?
|
||||
cc->size->win_gravity : NorthWestGravity;
|
||||
|
||||
switch (gravity) {
|
||||
case NorthWestGravity:
|
||||
case SouthWestGravity:
|
||||
case NorthEastGravity:
|
||||
case StaticGravity:
|
||||
dx = cc->bwidth;
|
||||
case NorthGravity:
|
||||
dy = cc->bwidth;
|
||||
break;
|
||||
}
|
||||
|
||||
cc->geom.x += mult * dx;
|
||||
cc->geom.y += mult * dy;
|
||||
}
|
||||
|
||||
void
|
||||
client_maximize(struct client_ctx *cc)
|
||||
{
|
||||
struct screen_ctx *sc = CCTOSC(cc);
|
||||
int xmax = sc->xmax, ymax = sc->ymax;
|
||||
int x_org = 0, y_org = 0;
|
||||
|
||||
if (cc->flags & CLIENT_MAXIMIZED) {
|
||||
cc->geom = cc->savegeom;
|
||||
} else {
|
||||
if (!(cc->flags & CLIENT_VMAXIMIZED))
|
||||
cc->savegeom = cc->geom;
|
||||
cc->geom.x = Conf.gap_left;
|
||||
cc->geom.y = Conf.gap_top;
|
||||
cc->geom.height = sc->ymax - (Conf.gap_top + Conf.gap_bottom);
|
||||
cc->geom.width = sc->xmax - (Conf.gap_left + Conf.gap_right);
|
||||
if (HasXinerama) {
|
||||
XineramaScreenInfo *xine;
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
xine = screen_find_xinerama(CCTOSC(cc),
|
||||
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:
|
||||
cc->geom.x = x_org - cc->bwidth + Conf.gap_left;
|
||||
cc->geom.y = y_org - cc->bwidth + Conf.gap_top;
|
||||
cc->geom.height = ymax - (Conf.gap_top + Conf.gap_bottom);
|
||||
cc->geom.width = xmax - (Conf.gap_left + Conf.gap_right);
|
||||
cc->flags |= CLIENT_DOMAXIMIZE;
|
||||
}
|
||||
|
||||
@@ -342,15 +279,27 @@ void
|
||||
client_vertmaximize(struct client_ctx *cc)
|
||||
{
|
||||
struct screen_ctx *sc = CCTOSC(cc);
|
||||
int y_org = 0, ymax = sc->ymax;
|
||||
|
||||
if (cc->flags & CLIENT_VMAXIMIZED) {
|
||||
cc->geom = cc->savegeom;
|
||||
} else {
|
||||
if (!(cc->flags & CLIENT_MAXIMIZED))
|
||||
cc->savegeom = cc->geom;
|
||||
cc->geom.y = cc->bwidth + Conf.gap_top;
|
||||
cc->geom.height = (sc->ymax - cc->bwidth * 2) -
|
||||
(Conf.gap_top + Conf.gap_bottom);
|
||||
if (HasXinerama) {
|
||||
XineramaScreenInfo *xine;
|
||||
xine = screen_find_xinerama(CCTOSC(cc),
|
||||
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:
|
||||
cc->geom.y = y_org + Conf.gap_top;
|
||||
cc->geom.height = ymax - (cc->bwidth * 2) - (Conf.gap_top +
|
||||
Conf.gap_bottom);
|
||||
cc->flags |= CLIENT_DOVMAXIMIZE;
|
||||
}
|
||||
|
||||
@@ -371,32 +320,28 @@ client_resize(struct client_ctx *cc)
|
||||
cc->flags |= CLIENT_VMAXIMIZED;
|
||||
}
|
||||
|
||||
XMoveResizeWindow(X_Dpy, cc->pwin, cc->geom.x - cc->bwidth,
|
||||
cc->geom.y - cc->bwidth, cc->geom.width + cc->bwidth*2,
|
||||
cc->geom.height + cc->bwidth*2);
|
||||
XMoveResizeWindow(X_Dpy, cc->win, cc->bwidth, cc->bwidth,
|
||||
cc->geom.width, cc->geom.height);
|
||||
XMoveResizeWindow(X_Dpy, cc->win, cc->geom.x,
|
||||
cc->geom.y, cc->geom.width, cc->geom.height);
|
||||
xev_reconfig(cc);
|
||||
}
|
||||
|
||||
void
|
||||
client_move(struct client_ctx *cc)
|
||||
{
|
||||
XMoveWindow(X_Dpy, cc->pwin,
|
||||
cc->geom.x - cc->bwidth, cc->geom.y - cc->bwidth);
|
||||
XMoveWindow(X_Dpy, cc->win, cc->geom.x, cc->geom.y);
|
||||
xev_reconfig(cc);
|
||||
}
|
||||
|
||||
void
|
||||
client_lower(struct client_ctx *cc)
|
||||
{
|
||||
XLowerWindow(X_Dpy, cc->pwin);
|
||||
XLowerWindow(X_Dpy, cc->win);
|
||||
}
|
||||
|
||||
void
|
||||
client_raise(struct client_ctx *cc)
|
||||
{
|
||||
XRaiseWindow(X_Dpy, cc->pwin);
|
||||
XRaiseWindow(X_Dpy, cc->win);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -414,7 +359,7 @@ client_ptrwarp(struct client_ctx *cc)
|
||||
else
|
||||
client_raise(cc);
|
||||
|
||||
xu_ptr_setpos(cc->pwin, x, y);
|
||||
xu_ptr_setpos(cc->win, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -422,8 +367,8 @@ client_ptrsave(struct client_ctx *cc)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
xu_ptr_getpos(cc->pwin, &x, &y);
|
||||
if (_inwindowbounds(cc, x, y)) {
|
||||
xu_ptr_getpos(cc->win, &x, &y);
|
||||
if (_client_inbound(cc, x, y)) {
|
||||
cc->ptr.x = x;
|
||||
cc->ptr.y = y;
|
||||
}
|
||||
@@ -433,7 +378,7 @@ void
|
||||
client_hide(struct client_ctx *cc)
|
||||
{
|
||||
/* XXX - add wm_state stuff */
|
||||
XUnmapWindow(X_Dpy, cc->pwin);
|
||||
XUnmapWindow(X_Dpy, cc->win);
|
||||
|
||||
cc->active = 0;
|
||||
cc->flags |= CLIENT_HIDDEN;
|
||||
@@ -446,7 +391,7 @@ client_hide(struct client_ctx *cc)
|
||||
void
|
||||
client_unhide(struct client_ctx *cc)
|
||||
{
|
||||
XMapRaised(X_Dpy, cc->pwin);
|
||||
XMapRaised(X_Dpy, cc->win);
|
||||
|
||||
cc->highlight = 0;
|
||||
cc->flags &= ~CLIENT_HIDDEN;
|
||||
@@ -455,88 +400,44 @@ client_unhide(struct client_ctx *cc)
|
||||
|
||||
void
|
||||
client_draw_border(struct client_ctx *cc)
|
||||
{
|
||||
struct screen_ctx *sc = CCTOSC(cc);
|
||||
|
||||
if (cc->active) {
|
||||
XSetWindowBackground(X_Dpy, cc->pwin, client_bg_pixel(cc));
|
||||
XClearWindow(X_Dpy, cc->pwin);
|
||||
|
||||
if (!cc->highlight && cc->bwidth > 1)
|
||||
XDrawRectangle(X_Dpy, cc->pwin, sc->gc, 1, 1,
|
||||
cc->geom.width + cc->bwidth,
|
||||
cc->geom.height + cc->bwidth);
|
||||
} else {
|
||||
if (cc->bwidth > 1)
|
||||
XSetWindowBackgroundPixmap(X_Dpy,
|
||||
cc->pwin, client_bg_pixmap(cc));
|
||||
|
||||
XClearWindow(X_Dpy, cc->pwin);
|
||||
}
|
||||
}
|
||||
|
||||
u_long
|
||||
client_bg_pixel(struct client_ctx *cc)
|
||||
{
|
||||
struct screen_ctx *sc = CCTOSC(cc);
|
||||
u_long pixl;
|
||||
|
||||
switch (cc->highlight) {
|
||||
case CLIENT_HIGHLIGHT_BLUE:
|
||||
pixl = sc->bluepixl;
|
||||
break;
|
||||
case CLIENT_HIGHLIGHT_RED:
|
||||
pixl = sc->redpixl;
|
||||
break;
|
||||
default:
|
||||
pixl = sc->blackpixl;
|
||||
break;
|
||||
}
|
||||
if (cc->active)
|
||||
switch (cc->highlight) {
|
||||
case CLIENT_HIGHLIGHT_BLUE:
|
||||
pixl = sc->bluepixl;
|
||||
break;
|
||||
case CLIENT_HIGHLIGHT_RED:
|
||||
pixl = sc->redpixl;
|
||||
break;
|
||||
default:
|
||||
pixl = sc->whitepixl;
|
||||
break;
|
||||
}
|
||||
else
|
||||
pixl = sc->graypixl;
|
||||
|
||||
return (pixl);
|
||||
}
|
||||
|
||||
Pixmap
|
||||
client_bg_pixmap(struct client_ctx *cc)
|
||||
{
|
||||
struct screen_ctx *sc = CCTOSC(cc);
|
||||
Pixmap pix;
|
||||
|
||||
switch (cc->highlight) {
|
||||
case CLIENT_HIGHLIGHT_BLUE:
|
||||
pix = sc->blue;
|
||||
break;
|
||||
case CLIENT_HIGHLIGHT_RED:
|
||||
pix = sc->red;
|
||||
break;
|
||||
default:
|
||||
pix = sc->gray;
|
||||
break;
|
||||
}
|
||||
|
||||
return (pix);
|
||||
XSetWindowBorderWidth(X_Dpy, cc->win, cc->bwidth);
|
||||
XSetWindowBorder(X_Dpy, cc->win, pixl);
|
||||
}
|
||||
|
||||
void
|
||||
client_update(struct client_ctx *cc)
|
||||
{
|
||||
Atom *p, wm_delete, wm_protocols, wm_take_focus;
|
||||
Atom *p;
|
||||
int i;
|
||||
long n;
|
||||
|
||||
/* XXX cache these. */
|
||||
wm_delete = XInternAtom(X_Dpy, "WM_DELETE_WINDOW", False);
|
||||
wm_protocols = XInternAtom(X_Dpy, "WM_PROTOCOLS", False);
|
||||
wm_take_focus = XInternAtom(X_Dpy, "WM_TAKE_FOCUS", False);
|
||||
|
||||
if ((n = xu_getprop(cc, wm_protocols,
|
||||
if ((n = xu_getprop(cc, WM_PROTOCOLS,
|
||||
XA_ATOM, 20L, (u_char **)&p)) <= 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
if (p[i] == wm_delete)
|
||||
if (p[i] == WM_DELETE_WINDOW)
|
||||
cc->xproto |= CLIENT_PROTO_DELETE;
|
||||
else if (p[i] == wm_take_focus)
|
||||
else if (p[i] == WM_TAKE_FOCUS)
|
||||
cc->xproto |= CLIENT_PROTO_TAKEFOCUS;
|
||||
|
||||
XFree(p);
|
||||
@@ -545,14 +446,9 @@ client_update(struct client_ctx *cc)
|
||||
void
|
||||
client_send_delete(struct client_ctx *cc)
|
||||
{
|
||||
Atom wm_delete, wm_protocols;
|
||||
|
||||
/* XXX - cache */
|
||||
wm_delete = XInternAtom(X_Dpy, "WM_DELETE_WINDOW", False);
|
||||
wm_protocols = XInternAtom(X_Dpy, "WM_PROTOCOLS", False);
|
||||
|
||||
if (cc->xproto & CLIENT_PROTO_DELETE)
|
||||
xu_sendmsg(cc, wm_protocols, wm_delete);
|
||||
xu_sendmsg(cc, WM_PROTOCOLS, WM_DELETE_WINDOW);
|
||||
else
|
||||
XKillClient(X_Dpy, cc->win);
|
||||
}
|
||||
@@ -667,46 +563,68 @@ void
|
||||
client_placecalc(struct client_ctx *cc)
|
||||
{
|
||||
struct screen_ctx *sc = CCTOSC(cc);
|
||||
int yslack, xslack, xmouse, ymouse;
|
||||
|
||||
yslack = sc->ymax - cc->geom.height - cc->bwidth;
|
||||
xslack = sc->xmax - cc->geom.width - cc->bwidth;
|
||||
|
||||
xu_ptr_getpos(sc->rootwin, &xmouse, &ymouse);
|
||||
|
||||
xmouse = MAX(xmouse, cc->bwidth) - cc->geom.width / 2;
|
||||
ymouse = MAX(ymouse, cc->bwidth) - cc->geom.height / 2;
|
||||
|
||||
xmouse = MAX(xmouse, (int)cc->bwidth);
|
||||
ymouse = MAX(ymouse, (int)cc->bwidth);
|
||||
int xslack, yslack;
|
||||
|
||||
if (cc->size->flags & USPosition) {
|
||||
if (cc->size->x >= 0)
|
||||
cc->geom.x = MAX(MIN(cc->size->x, xslack), cc->bwidth);
|
||||
else
|
||||
cc->geom.x = cc->bwidth;
|
||||
if (cc->size->y >= 0)
|
||||
cc->geom.y = MAX(MIN(cc->size->y, yslack), cc->bwidth);
|
||||
else
|
||||
cc->geom.y = cc->bwidth;
|
||||
/*
|
||||
* Ignore XINERAMA screens, just make sure it's somewhere
|
||||
* in the virtual desktop. else it stops people putting xterms
|
||||
* at startup in the screen the mouse doesn't start in *sigh*.
|
||||
* XRandR bits mean that {x,y}max shouldn't be outside what's
|
||||
* currently there.
|
||||
*/
|
||||
xslack = sc->xmax - cc->geom.width - cc->bwidth * 2;
|
||||
yslack = sc->ymax - cc->geom.height - cc->bwidth * 2;
|
||||
if (cc->size->x > 0)
|
||||
cc->geom.x = MIN(cc->size->x, xslack);
|
||||
if (cc->size->y > 0)
|
||||
cc->geom.y = MIN(cc->size->y, yslack);
|
||||
} else {
|
||||
if (xslack >= 0) {
|
||||
XineramaScreenInfo *info;
|
||||
int xmouse, ymouse, xorig, yorig;
|
||||
int xmax, ymax;
|
||||
|
||||
xu_ptr_getpos(sc->rootwin, &xmouse, &ymouse);
|
||||
if (HasXinerama) {
|
||||
info = screen_find_xinerama(sc, xmouse, ymouse);
|
||||
if (info == NULL)
|
||||
goto noxine;
|
||||
xorig = info->x_org;
|
||||
yorig = info->y_org;
|
||||
xmax = xorig + info->width;
|
||||
ymax = yorig + info->height;
|
||||
} else {
|
||||
noxine:
|
||||
xorig = yorig = 0;
|
||||
xmax = sc->xmax;
|
||||
ymax = sc->ymax;
|
||||
}
|
||||
xmouse = MAX(xmouse, xorig) - cc->geom.width / 2;
|
||||
ymouse = MAX(ymouse, yorig) - cc->geom.height / 2;
|
||||
|
||||
xmouse = MAX(xmouse, xorig);
|
||||
ymouse = MAX(ymouse, yorig);
|
||||
|
||||
xslack = xmax - cc->geom.width - cc->bwidth * 2;
|
||||
yslack = ymax - cc->geom.height - cc->bwidth * 2;
|
||||
|
||||
if (xslack >= xorig) {
|
||||
cc->geom.x = MAX(MIN(xmouse, xslack),
|
||||
Conf.gap_left + cc->bwidth);
|
||||
xorig + Conf.gap_left);
|
||||
if (cc->geom.x > (xslack - Conf.gap_right))
|
||||
cc->geom.x -= Conf.gap_right;
|
||||
} else {
|
||||
cc->geom.x = cc->bwidth + Conf.gap_left;
|
||||
cc->geom.width = sc->xmax - Conf.gap_left;
|
||||
cc->geom.x = xorig + Conf.gap_left;
|
||||
cc->geom.width = xmax - Conf.gap_left;
|
||||
}
|
||||
if (yslack >= 0) {
|
||||
if (yslack >= yorig) {
|
||||
cc->geom.y = MAX(MIN(ymouse, yslack),
|
||||
Conf.gap_top + cc->bwidth);
|
||||
yorig + Conf.gap_top);
|
||||
if (cc->geom.y > (yslack - Conf.gap_bottom))
|
||||
cc->geom.y -= Conf.gap_bottom;
|
||||
} else {
|
||||
cc->geom.y = cc->bwidth + Conf.gap_top;
|
||||
cc->geom.height = sc->ymax - Conf.gap_top;
|
||||
cc->geom.y = yorig + Conf.gap_top;
|
||||
cc->geom.height = ymax - Conf.gap_top;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -734,7 +652,6 @@ client_gethints(struct client_ctx *cc)
|
||||
XClassHint xch;
|
||||
int argc;
|
||||
char **argv;
|
||||
Atom mha;
|
||||
struct mwm_hints *mwmh;
|
||||
|
||||
if (XGetClassHint(X_Dpy, cc->win, &xch)) {
|
||||
@@ -744,9 +661,8 @@ client_gethints(struct client_ctx *cc)
|
||||
cc->app_class = xch.res_class;
|
||||
}
|
||||
|
||||
mha = XInternAtom(X_Dpy, "_MOTIF_WM_HINTS", False);
|
||||
if (xu_getprop(cc, mha, mha, PROP_MWM_HINTS_ELEMENTS,
|
||||
(u_char **)&mwmh) == MWM_NUMHINTS)
|
||||
if (xu_getprop(cc, _MOTIF_WM_HINTS, _MOTIF_WM_HINTS,
|
||||
PROP_MWM_HINTS_ELEMENTS, (u_char **)&mwmh) == MWM_NUMHINTS)
|
||||
if (mwmh->flags & MWM_HINTS_DECORATIONS &&
|
||||
!(mwmh->decorations & MWM_DECOR_ALL) &&
|
||||
!(mwmh->decorations & MWM_DECOR_BORDER))
|
||||
@@ -783,12 +699,11 @@ client_freehints(struct client_ctx *cc)
|
||||
XFree(cc->app_name);
|
||||
if (cc->app_class != NULL)
|
||||
XFree(cc->app_class);
|
||||
if (cc->app_cliarg != NULL)
|
||||
xfree(cc->app_cliarg);
|
||||
xfree(cc->app_cliarg);
|
||||
}
|
||||
|
||||
int
|
||||
_inwindowbounds(struct client_ctx *cc, int x, int y)
|
||||
static int
|
||||
_client_inbound(struct client_ctx *cc, int x, int y)
|
||||
{
|
||||
return (x < cc->geom.width && x >= 0 &&
|
||||
y < cc->geom.height && y >= 0);
|
||||
|
170
conf.c
170
conf.c
@@ -76,6 +76,8 @@ void
|
||||
conf_init(struct conf *c)
|
||||
{
|
||||
c->flags = 0;
|
||||
c->bwidth = CONF_BWIDTH;
|
||||
c->mamount = CONF_MAMOUNT;
|
||||
|
||||
TAILQ_INIT(&c->ignoreq);
|
||||
TAILQ_INIT(&c->cmdq);
|
||||
@@ -158,6 +160,47 @@ conf_init(struct conf *c)
|
||||
c->DefaultFontName = xstrdup(DEFAULTFONTNAME);
|
||||
}
|
||||
|
||||
void
|
||||
conf_clear(struct conf *c)
|
||||
{
|
||||
struct autogroupwin *ag;
|
||||
struct keybinding *kb;
|
||||
struct winmatch *wm;
|
||||
struct cmd *cmd;
|
||||
struct mousebinding *mb;
|
||||
|
||||
while ((cmd = TAILQ_FIRST(&c->cmdq)) != NULL) {
|
||||
TAILQ_REMOVE(&c->cmdq, cmd, entry);
|
||||
xfree(cmd);
|
||||
}
|
||||
|
||||
while ((kb = TAILQ_FIRST(&c->keybindingq)) != NULL) {
|
||||
TAILQ_REMOVE(&c->keybindingq, kb, entry);
|
||||
xfree(kb);
|
||||
}
|
||||
|
||||
while ((ag = TAILQ_FIRST(&c->autogroupq)) != NULL) {
|
||||
TAILQ_REMOVE(&c->autogroupq, ag, entry);
|
||||
xfree(ag->class);
|
||||
if (ag->name)
|
||||
xfree(ag->name);
|
||||
xfree(ag->group);
|
||||
xfree(ag);
|
||||
}
|
||||
|
||||
while ((wm = TAILQ_FIRST(&c->ignoreq)) != NULL) {
|
||||
TAILQ_REMOVE(&c->ignoreq, wm, entry);
|
||||
xfree(wm);
|
||||
}
|
||||
|
||||
while ((mb = TAILQ_FIRST(&c->mousebindingq)) != NULL) {
|
||||
TAILQ_REMOVE(&c->mousebindingq, mb, entry);
|
||||
xfree(mb);
|
||||
}
|
||||
|
||||
xfree(c->DefaultFontName);
|
||||
}
|
||||
|
||||
void
|
||||
conf_setup(struct conf *c, const char *conf_file)
|
||||
{
|
||||
@@ -201,93 +244,93 @@ conf_client(struct client_ctx *cc)
|
||||
} else
|
||||
ignore = 1;
|
||||
|
||||
cc->bwidth = ignore ? 0 : 3;
|
||||
cc->bwidth = ignore ? 0 : Conf.bwidth;
|
||||
cc->flags |= ignore ? CLIENT_IGNORE : 0;
|
||||
}
|
||||
|
||||
struct {
|
||||
char *tag;
|
||||
void (*handler)(struct client_ctx *, void *);
|
||||
int flags;
|
||||
void *argument;
|
||||
char *tag;
|
||||
void (*handler)(struct client_ctx *, union arg *);
|
||||
int flags;
|
||||
union arg argument;
|
||||
} name_to_kbfunc[] = {
|
||||
{ "lower", kbfunc_client_lower, KBFLAG_NEEDCLIENT, 0 },
|
||||
{ "raise", kbfunc_client_raise, KBFLAG_NEEDCLIENT, 0 },
|
||||
{ "search", kbfunc_client_search, 0, 0 },
|
||||
{ "menusearch", kbfunc_menu_search, 0, 0 },
|
||||
{ "hide", kbfunc_client_hide, KBFLAG_NEEDCLIENT, 0 },
|
||||
{ "cycle", kbfunc_client_cycle, 0, (void *)CWM_CYCLE },
|
||||
{ "rcycle", kbfunc_client_cycle, 0, (void *)CWM_RCYCLE },
|
||||
{ "label", kbfunc_client_label, KBFLAG_NEEDCLIENT, 0 },
|
||||
{ "delete", kbfunc_client_delete, KBFLAG_NEEDCLIENT, 0 },
|
||||
{ "group1", kbfunc_client_group, 0, (void *)1 },
|
||||
{ "group2", kbfunc_client_group, 0, (void *)2 },
|
||||
{ "group3", kbfunc_client_group, 0, (void *)3 },
|
||||
{ "group4", kbfunc_client_group, 0, (void *)4 },
|
||||
{ "group5", kbfunc_client_group, 0, (void *)5 },
|
||||
{ "group6", kbfunc_client_group, 0, (void *)6 },
|
||||
{ "group7", kbfunc_client_group, 0, (void *)7 },
|
||||
{ "group8", kbfunc_client_group, 0, (void *)8 },
|
||||
{ "group9", kbfunc_client_group, 0, (void *)9 },
|
||||
{ "nogroup", kbfunc_client_nogroup, 0, 0 },
|
||||
{ "cyclegroup", kbfunc_client_cyclegroup, 0, (void *)CWM_CYCLEGROUP },
|
||||
{ "rcyclegroup", kbfunc_client_cyclegroup, 0, (void *)CWM_RCYCLEGROUP },
|
||||
{ "grouptoggle", kbfunc_client_grouptoggle, KBFLAG_NEEDCLIENT, 0},
|
||||
{ "maximize", kbfunc_client_maximize, KBFLAG_NEEDCLIENT, 0 },
|
||||
{ "vmaximize", kbfunc_client_vmaximize, KBFLAG_NEEDCLIENT, 0 },
|
||||
{ "reload", kbfunc_reload, 0, 0 },
|
||||
{ "quit", kbfunc_quit_wm, 0, 0 },
|
||||
{ "exec", kbfunc_exec, 0, (void *)CWM_EXEC_PROGRAM },
|
||||
{ "exec_wm", kbfunc_exec, 0, (void *)CWM_EXEC_WM },
|
||||
{ "ssh", kbfunc_ssh, 0, 0 },
|
||||
{ "terminal", kbfunc_term, 0, 0 },
|
||||
{ "lock", kbfunc_lock, 0, 0 },
|
||||
{ "lower", kbfunc_client_lower, KBFLAG_NEEDCLIENT, {0} },
|
||||
{ "raise", kbfunc_client_raise, KBFLAG_NEEDCLIENT, {0} },
|
||||
{ "search", kbfunc_client_search, 0, {0} },
|
||||
{ "menusearch", kbfunc_menu_search, 0, {0} },
|
||||
{ "hide", kbfunc_client_hide, KBFLAG_NEEDCLIENT, {0} },
|
||||
{ "cycle", kbfunc_client_cycle, 0, {.i = CWM_CYCLE} },
|
||||
{ "rcycle", kbfunc_client_cycle, 0, {.i = CWM_RCYCLE} },
|
||||
{ "label", kbfunc_client_label, KBFLAG_NEEDCLIENT, {0} },
|
||||
{ "delete", kbfunc_client_delete, KBFLAG_NEEDCLIENT, {0} },
|
||||
{ "group1", kbfunc_client_group, 0, {.i = 1} },
|
||||
{ "group2", kbfunc_client_group, 0, {.i = 2} },
|
||||
{ "group3", kbfunc_client_group, 0, {.i = 3} },
|
||||
{ "group4", kbfunc_client_group, 0, {.i = 4} },
|
||||
{ "group5", kbfunc_client_group, 0, {.i = 5} },
|
||||
{ "group6", kbfunc_client_group, 0, {.i = 6} },
|
||||
{ "group7", kbfunc_client_group, 0, {.i = 7} },
|
||||
{ "group8", kbfunc_client_group, 0, {.i = 8} },
|
||||
{ "group9", kbfunc_client_group, 0, {.i = 9} },
|
||||
{ "nogroup", kbfunc_client_nogroup, 0, {0} },
|
||||
{ "cyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_CYCLEGROUP} },
|
||||
{ "rcyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_RCYCLEGROUP} },
|
||||
{ "grouptoggle", kbfunc_client_grouptoggle, KBFLAG_NEEDCLIENT, {0}},
|
||||
{ "maximize", kbfunc_client_maximize, KBFLAG_NEEDCLIENT, {0} },
|
||||
{ "vmaximize", kbfunc_client_vmaximize, KBFLAG_NEEDCLIENT, {0} },
|
||||
{ "reload", kbfunc_reload, 0, {0} },
|
||||
{ "quit", kbfunc_quit_wm, 0, {0} },
|
||||
{ "exec", kbfunc_exec, 0, {.i = CWM_EXEC_PROGRAM} },
|
||||
{ "exec_wm", kbfunc_exec, 0, {.i = CWM_EXEC_WM} },
|
||||
{ "ssh", kbfunc_ssh, 0, {0} },
|
||||
{ "terminal", kbfunc_term, 0, {0} },
|
||||
{ "lock", kbfunc_lock, 0, {0} },
|
||||
{ "moveup", kbfunc_moveresize, KBFLAG_NEEDCLIENT,
|
||||
(void *)(CWM_UP|CWM_MOVE) },
|
||||
{.i = (CWM_UP|CWM_MOVE)} },
|
||||
{ "movedown", kbfunc_moveresize, KBFLAG_NEEDCLIENT,
|
||||
(void *)(CWM_DOWN|CWM_MOVE) },
|
||||
{.i = (CWM_DOWN|CWM_MOVE)} },
|
||||
{ "moveright", kbfunc_moveresize, KBFLAG_NEEDCLIENT,
|
||||
(void *)(CWM_RIGHT|CWM_MOVE) },
|
||||
{.i = (CWM_RIGHT|CWM_MOVE)} },
|
||||
{ "moveleft", kbfunc_moveresize, KBFLAG_NEEDCLIENT,
|
||||
(void *)(CWM_LEFT|CWM_MOVE) },
|
||||
{.i = (CWM_LEFT|CWM_MOVE)} },
|
||||
{ "bigmoveup", kbfunc_moveresize, KBFLAG_NEEDCLIENT,
|
||||
(void *)(CWM_UP|CWM_MOVE|CWM_BIGMOVE) },
|
||||
{.i = (CWM_UP|CWM_MOVE|CWM_BIGMOVE)} },
|
||||
{ "bigmovedown", kbfunc_moveresize, KBFLAG_NEEDCLIENT,
|
||||
(void *)(CWM_DOWN|CWM_MOVE|CWM_BIGMOVE) },
|
||||
{.i = (CWM_DOWN|CWM_MOVE|CWM_BIGMOVE)} },
|
||||
{ "bigmoveright", kbfunc_moveresize, KBFLAG_NEEDCLIENT,
|
||||
(void *)(CWM_RIGHT|CWM_MOVE|CWM_BIGMOVE) },
|
||||
{.i = (CWM_RIGHT|CWM_MOVE|CWM_BIGMOVE)} },
|
||||
{ "bigmoveleft", kbfunc_moveresize, KBFLAG_NEEDCLIENT,
|
||||
(void *)(CWM_LEFT|CWM_MOVE|CWM_BIGMOVE) },
|
||||
{.i = (CWM_LEFT|CWM_MOVE|CWM_BIGMOVE)} },
|
||||
{ "resizeup", kbfunc_moveresize, KBFLAG_NEEDCLIENT,
|
||||
(void *)(CWM_UP|CWM_RESIZE) },
|
||||
{.i = (CWM_UP|CWM_RESIZE)} },
|
||||
{ "resizedown", kbfunc_moveresize, KBFLAG_NEEDCLIENT,
|
||||
(void *)(CWM_DOWN|CWM_RESIZE) },
|
||||
{.i = (CWM_DOWN|CWM_RESIZE)} },
|
||||
{ "resizeright", kbfunc_moveresize, KBFLAG_NEEDCLIENT,
|
||||
(void *)(CWM_RIGHT|CWM_RESIZE) },
|
||||
{.i = (CWM_RIGHT|CWM_RESIZE)} },
|
||||
{ "resizeleft", kbfunc_moveresize, KBFLAG_NEEDCLIENT,
|
||||
(void *)(CWM_LEFT|CWM_RESIZE) },
|
||||
{.i = (CWM_LEFT|CWM_RESIZE)} },
|
||||
{ "bigresizeup", kbfunc_moveresize, KBFLAG_NEEDCLIENT,
|
||||
(void *)(CWM_UP|CWM_RESIZE|CWM_BIGMOVE) },
|
||||
{.i = (CWM_UP|CWM_RESIZE|CWM_BIGMOVE)} },
|
||||
{ "bigresizedown", kbfunc_moveresize, KBFLAG_NEEDCLIENT,
|
||||
(void *)(CWM_DOWN|CWM_RESIZE|CWM_BIGMOVE) },
|
||||
{.i = (CWM_DOWN|CWM_RESIZE|CWM_BIGMOVE)} },
|
||||
{ "bigresizeright", kbfunc_moveresize, KBFLAG_NEEDCLIENT,
|
||||
(void *)(CWM_RIGHT|CWM_RESIZE|CWM_BIGMOVE) },
|
||||
{.i = (CWM_RIGHT|CWM_RESIZE|CWM_BIGMOVE)} },
|
||||
{ "bigresizeleft", kbfunc_moveresize, KBFLAG_NEEDCLIENT,
|
||||
(void *)(CWM_LEFT|CWM_RESIZE|CWM_BIGMOVE) },
|
||||
{ "ptrmoveup", kbfunc_moveresize, 0, (void *)(CWM_UP|CWM_PTRMOVE) },
|
||||
{ "ptrmovedown", kbfunc_moveresize, 0, (void *)(CWM_DOWN|CWM_PTRMOVE) },
|
||||
{ "ptrmoveleft", kbfunc_moveresize, 0, (void *)(CWM_LEFT|CWM_PTRMOVE) },
|
||||
{.i = (CWM_LEFT|CWM_RESIZE|CWM_BIGMOVE)} },
|
||||
{ "ptrmoveup", kbfunc_moveresize, 0, {.i = (CWM_UP|CWM_PTRMOVE)} },
|
||||
{ "ptrmovedown", kbfunc_moveresize, 0, {.i = (CWM_DOWN|CWM_PTRMOVE)} },
|
||||
{ "ptrmoveleft", kbfunc_moveresize, 0, {.i = (CWM_LEFT|CWM_PTRMOVE)} },
|
||||
{ "ptrmoveright", kbfunc_moveresize, 0,
|
||||
(void *)(CWM_RIGHT|CWM_PTRMOVE) },
|
||||
{.i = (CWM_RIGHT|CWM_PTRMOVE)} },
|
||||
{ "bigptrmoveup", kbfunc_moveresize, 0,
|
||||
(void *)(CWM_UP|CWM_PTRMOVE|CWM_BIGMOVE) },
|
||||
{.i = (CWM_UP|CWM_PTRMOVE|CWM_BIGMOVE)} },
|
||||
{ "bigptrmovedown", kbfunc_moveresize, 0,
|
||||
(void *)(CWM_DOWN|CWM_PTRMOVE|CWM_BIGMOVE) },
|
||||
{.i = (CWM_DOWN|CWM_PTRMOVE|CWM_BIGMOVE)} },
|
||||
{ "bigptrmoveleft", kbfunc_moveresize, 0,
|
||||
(void *)(CWM_LEFT|CWM_PTRMOVE|CWM_BIGMOVE) },
|
||||
{.i = (CWM_LEFT|CWM_PTRMOVE|CWM_BIGMOVE)} },
|
||||
{ "bigptrmoveright", kbfunc_moveresize, 0,
|
||||
(void *)(CWM_RIGHT|CWM_PTRMOVE|CWM_BIGMOVE) },
|
||||
{ NULL, NULL, 0, 0},
|
||||
{.i = (CWM_RIGHT|CWM_PTRMOVE|CWM_BIGMOVE)} },
|
||||
{ NULL, NULL, 0, {0}},
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -387,7 +430,7 @@ conf_bindname(struct conf *c, char *name, char *binding)
|
||||
}
|
||||
|
||||
current_binding->callback = kbfunc_cmdexec;
|
||||
current_binding->argument = xstrdup(binding);
|
||||
current_binding->argument.c = xstrdup(binding);
|
||||
current_binding->flags = 0;
|
||||
conf_grab(c, current_binding);
|
||||
TAILQ_INSERT_TAIL(&c->keybindingq, current_binding, entry);
|
||||
@@ -528,7 +571,8 @@ conf_grab_mouse(struct client_ctx *cc)
|
||||
break;
|
||||
default:
|
||||
warnx("strange button in mousebinding\n");
|
||||
continue;
|
||||
}
|
||||
xu_btn_grab(cc->pwin, mb->modmask, button);
|
||||
xu_btn_grab(cc->win, mb->modmask, button);
|
||||
}
|
||||
}
|
||||
|
4
cwm.1
4
cwm.1
@@ -14,8 +14,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.\" The following requests are required for all man pages.
|
||||
.Dd $Mdocdate: July 11 2008 $
|
||||
.Dd $Mdocdate: September 22 2008 $
|
||||
.Dt CWM 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -240,6 +239,7 @@ option is given.
|
||||
.Sh FILES
|
||||
.Bl -tag -width Ds
|
||||
.It Pa ~/.cwmrc
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr cwmrc 5
|
||||
.Sh AUTHORS
|
||||
|
117
cwmrc.5
117
cwmrc.5
@@ -14,8 +14,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.\" The following requests are required for all man pages.
|
||||
.Dd $Mdocdate: July 11 2008 $
|
||||
.Dd $Mdocdate: February 7 2009 $
|
||||
.Dt CWMRC 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -35,7 +34,7 @@ properties, where
|
||||
.Ar group
|
||||
is a number between 0 and 9.
|
||||
If the group number is 0, then the window will not be grouped; this to
|
||||
allow for
|
||||
allow for
|
||||
.Dq sticky
|
||||
windows in sticky group mode.
|
||||
.Pp
|
||||
@@ -81,6 +80,10 @@ can be used to remove the named keybinding.
|
||||
This can be used to remove a binding which conflicts with an
|
||||
application.
|
||||
.Pp
|
||||
.It Ic borderwidth Ar pixels
|
||||
Set the window border width to
|
||||
.Ar pixels .
|
||||
.Pp
|
||||
.It Ic command Ar name Ar path
|
||||
Every
|
||||
.Ar name
|
||||
@@ -123,8 +126,9 @@ can be used for applications such as
|
||||
where the user may wish to remain visible.
|
||||
.Pp
|
||||
.It Ic ignore Ar windowname
|
||||
Ignore drawing borders around a window with the name
|
||||
.Ar windowname .
|
||||
Ignore windows with the name
|
||||
.Ar windowname
|
||||
when drawing borders and cycling through windows.
|
||||
.Pp
|
||||
.It Ic mousebind Ar buttons Ar command
|
||||
Cause the creation of a mouse binding, or replacement of a default
|
||||
@@ -135,7 +139,7 @@ The modifier keys come first, followed by a
|
||||
The following modifiers are recognised:
|
||||
.Pp
|
||||
.Bl -tag -width Ds -offset indent -compact
|
||||
.It C
|
||||
.It C
|
||||
The Control key.
|
||||
.It M
|
||||
The Meta key.
|
||||
@@ -165,6 +169,11 @@ may be taken from the
|
||||
.Sx MOUSEBIND COMMAND LIST
|
||||
(see below).
|
||||
.Pp
|
||||
.It Ic moveamount Ar pixels
|
||||
Set a default size for the keyboard movement bindings,
|
||||
in pixels.
|
||||
The default is 1.
|
||||
.Pp
|
||||
.It Ic sticky Ic yes Ns \&| Ns Ic no
|
||||
Toggle sticky group mode.
|
||||
The default behavior for new windows is to not assign any group.
|
||||
@@ -260,53 +269,101 @@ Maximize current window full-screen.
|
||||
.It vmaximize
|
||||
Maximize current window vertically.
|
||||
.It moveup
|
||||
Move window 1 pixel up.
|
||||
Move window
|
||||
.Ar moveamount
|
||||
pixels up.
|
||||
.It movedown
|
||||
Move window 1 pixel down.
|
||||
Move window
|
||||
.Ar moveamount
|
||||
pixels down.
|
||||
.It moveright
|
||||
Move window 1 pixel right.
|
||||
Move window
|
||||
.Ar moveamount
|
||||
pixels right.
|
||||
.It moveleft
|
||||
Move window 1 pixel left.
|
||||
Move window
|
||||
.Ar moveamount
|
||||
pixels left.
|
||||
.It bigmoveup
|
||||
Move window 10 pixels up.
|
||||
Move window 10 times
|
||||
.Ar moveamount
|
||||
pixels up.
|
||||
.It bigmovedown
|
||||
Move window 10 pixels down.
|
||||
Move window 10 times
|
||||
.Ar moveamount
|
||||
pixels down.
|
||||
.It bigmoveright
|
||||
Move window 10 pixels right.
|
||||
Move window 10 times
|
||||
.Ar moveamount
|
||||
pixels right.
|
||||
.It bigmoveleft
|
||||
Move window 10 pixels left.
|
||||
Move window 10 times
|
||||
.Ar moveamount
|
||||
pixels left.
|
||||
.It resizeup
|
||||
Resize window 1 pixel up.
|
||||
Resize window
|
||||
.Ar moveamount
|
||||
pixels up.
|
||||
.It resizedown
|
||||
Resize window 1 pixel down.
|
||||
Resize window
|
||||
.Ar moveamount
|
||||
pixels down.
|
||||
.It resizeright
|
||||
Resize window 1 pixel right.
|
||||
Resize window
|
||||
.Ar moveamount
|
||||
pixels right.
|
||||
.It resizeleft
|
||||
Resize window 1 pixel left.
|
||||
Resize window
|
||||
.Ar moveamount
|
||||
pixels left.
|
||||
.It bigresizeup
|
||||
Resize window 10 pixels up.
|
||||
Resize window 10 times
|
||||
.Ar moveamount
|
||||
pixels up.
|
||||
.It bigresizedown
|
||||
Resize window 10 pixels down.
|
||||
Resize window 10 times
|
||||
.Ar moveamount
|
||||
pixels down.
|
||||
.It bigresizeright
|
||||
Resize window 10 pixels right.
|
||||
Resize window 10 times
|
||||
.Ar moveamount
|
||||
pixels right.
|
||||
.It bigresizeleft
|
||||
Resize window 10 pixels left.
|
||||
Resize window 10 times
|
||||
.Ar moveamount
|
||||
pixels left.
|
||||
.It ptrmoveup
|
||||
Move pointer 1 pixel up.
|
||||
Move pointer
|
||||
.Ar moveamount
|
||||
pixels up.
|
||||
.It ptrmovedown
|
||||
Move pointer 1 pixel down.
|
||||
Move pointer
|
||||
.Ar moveamount
|
||||
pixels down.
|
||||
.It ptrmoveright
|
||||
Move pointer 1 pixel right.
|
||||
Move pointer
|
||||
.Ar moveamount
|
||||
pixels right.
|
||||
.It ptrmoveleft
|
||||
Move pointer 1 pixel left.
|
||||
Move pointer
|
||||
.Ar moveamount
|
||||
pixels left.
|
||||
.It bigptrmoveup
|
||||
Move pointer 10 pixels up.
|
||||
Move pointer 10 times
|
||||
.Ar moveamount
|
||||
pixels up.
|
||||
.It bigptrmovedown
|
||||
Move pointer 10 pixels down.
|
||||
Move pointer 10 times
|
||||
.Ar moveamount
|
||||
pixels down.
|
||||
.It bigptrmoveright
|
||||
Move pointer 10 pixels right.
|
||||
Move pointer 10 times
|
||||
.Ar moveamount
|
||||
pixels right.
|
||||
.It bigptrmoveleft
|
||||
Move pointer 10 pixels left.
|
||||
Move pointer 10 times
|
||||
.Ar moveamount
|
||||
pixels left.
|
||||
.El
|
||||
.Sh MOUSEBIND COMMAND LIST
|
||||
.Bl -tag -width 18n -compact
|
||||
|
2
font.c
2
font.c
@@ -68,7 +68,7 @@ font_make(struct screen_ctx *sc, const char *name)
|
||||
FcPattern *pat, *patx;
|
||||
XftResult res;
|
||||
|
||||
if ((pat = FcNameParse(name)) == NULL)
|
||||
if ((pat = FcNameParse((const FcChar8*)name)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
if ((patx = XftFontMatch(X_Dpy, sc->which, pat, &res)) != NULL)
|
||||
|
184
grab.c
184
grab.c
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
* 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 "headers.h"
|
||||
#include "calmwm.h"
|
||||
|
||||
static int _sweepcalc(struct client_ctx *, int, int, int, int);
|
||||
|
||||
#define ADJUST_HEIGHT(cc, dy) ((cc->geom.height - cc->geom.min_dy)/ dy)
|
||||
#define ADJUST_WIDTH(cc, dx) ((cc->geom.width - cc->geom.min_dx)/ dx)
|
||||
|
||||
void
|
||||
grab_sweep_draw(struct client_ctx *cc, int dx, int dy)
|
||||
{
|
||||
struct screen_ctx *sc = CCTOSC(cc);
|
||||
char asize[10]; /* fits "nnnnxnnnn\0" */
|
||||
int wide, height, wide_size, wide_name;
|
||||
int x = cc->geom.x, y = cc->geom.y;
|
||||
|
||||
snprintf(asize, sizeof(asize), "%dx%d",
|
||||
ADJUST_WIDTH(cc, dx), ADJUST_HEIGHT(cc, dy));
|
||||
wide_size = font_width(asize, strlen(asize)) + 4;
|
||||
wide_name = font_width(cc->name, strlen(cc->name)) + 4;
|
||||
wide = MAX(wide_size, wide_name);
|
||||
height = font_ascent() + font_descent() + 1;
|
||||
|
||||
XMoveResizeWindow(X_Dpy, sc->menuwin, x, y, wide, height * 2);
|
||||
XMapWindow(X_Dpy, sc->menuwin);
|
||||
XReparentWindow(X_Dpy, sc->menuwin, cc->win, 0, 0);
|
||||
XClearWindow(X_Dpy, sc->menuwin);
|
||||
font_draw(sc, cc->name, strlen(cc->name), sc->menuwin,
|
||||
2, font_ascent() + 1);
|
||||
font_draw(sc, asize, strlen(asize), sc->menuwin,
|
||||
wide / 2 - wide_size / 2, height + font_ascent() + 1);
|
||||
}
|
||||
|
||||
void
|
||||
grab_sweep(struct client_ctx *cc)
|
||||
{
|
||||
XEvent ev;
|
||||
struct screen_ctx *sc = CCTOSC(cc);
|
||||
int x = cc->geom.x, y = cc->geom.y, dx, dy;
|
||||
|
||||
dx = MAX(1, cc->size->width_inc);
|
||||
dy = MAX(1, cc->size->height_inc);
|
||||
|
||||
client_raise(cc);
|
||||
client_ptrsave(cc);
|
||||
|
||||
if (xu_ptr_grab(sc->rootwin, MouseMask, Cursor_resize) < 0)
|
||||
return;
|
||||
|
||||
xu_ptr_setpos(cc->win, cc->geom.width, cc->geom.height);
|
||||
grab_sweep_draw(cc, dx, dy);
|
||||
|
||||
for (;;) {
|
||||
/* Look for changes in ptr position. */
|
||||
XMaskEvent(X_Dpy, MouseMask|ExposureMask, &ev);
|
||||
|
||||
switch (ev.type) {
|
||||
case Expose:
|
||||
client_draw_border(cc);
|
||||
break;
|
||||
case MotionNotify:
|
||||
if (_sweepcalc(cc, x, y, ev.xmotion.x, ev.xmotion.y))
|
||||
/* Recompute window output */
|
||||
grab_sweep_draw(cc, dx, dy);
|
||||
|
||||
XMoveResizeWindow(X_Dpy, cc->pwin,
|
||||
cc->geom.x - cc->bwidth,
|
||||
cc->geom.y - cc->bwidth,
|
||||
cc->geom.width + cc->bwidth*2,
|
||||
cc->geom.height + cc->bwidth*2);
|
||||
XMoveResizeWindow(X_Dpy, cc->win,
|
||||
cc->bwidth, cc->bwidth,
|
||||
cc->geom.width, cc->geom.height);
|
||||
|
||||
client_do_shape(cc);
|
||||
break;
|
||||
case ButtonRelease:
|
||||
XUnmapWindow(X_Dpy, sc->menuwin);
|
||||
XReparentWindow(X_Dpy, sc->menuwin, sc->rootwin, 0, 0);
|
||||
xu_ptr_ungrab();
|
||||
|
||||
/* Make sure the pointer stays within the window. */
|
||||
if (cc->ptr.x > cc->geom.width)
|
||||
cc->ptr.x = cc->geom.width - cc->bwidth;
|
||||
if (cc->ptr.y > cc->geom.height)
|
||||
cc->ptr.y = cc->geom.height - cc->bwidth;
|
||||
client_ptrwarp(cc);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
void
|
||||
grab_drag(struct client_ctx *cc)
|
||||
{
|
||||
XEvent ev;
|
||||
struct screen_ctx *sc = CCTOSC(cc);
|
||||
int x = cc->geom.x, y = cc->geom.y, xm, ym;
|
||||
|
||||
client_raise(cc);
|
||||
|
||||
if (xu_ptr_grab(sc->rootwin, MouseMask, Cursor_move) < 0)
|
||||
return;
|
||||
|
||||
xu_ptr_getpos(sc->rootwin, &xm, &ym);
|
||||
|
||||
for (;;) {
|
||||
XMaskEvent(X_Dpy, MouseMask|ExposureMask, &ev);
|
||||
|
||||
switch (ev.type) {
|
||||
case Expose:
|
||||
client_draw_border(cc);
|
||||
break;
|
||||
case MotionNotify:
|
||||
cc->geom.x = x + (ev.xmotion.x - xm);
|
||||
cc->geom.y = y + (ev.xmotion.y - ym);
|
||||
|
||||
XMoveWindow(X_Dpy, cc->pwin,
|
||||
cc->geom.x - cc->bwidth, cc->geom.y - cc->bwidth);
|
||||
|
||||
break;
|
||||
case ButtonRelease:
|
||||
xu_ptr_ungrab();
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static int
|
||||
_sweepcalc(struct client_ctx *cc, int x, int y, int motionx, int motiony)
|
||||
{
|
||||
int width, height;
|
||||
|
||||
width = cc->geom.width;
|
||||
height = cc->geom.height;
|
||||
|
||||
cc->geom.width = abs(x - motionx);
|
||||
cc->geom.height = abs(y - motiony);
|
||||
|
||||
if (cc->size->flags & PResizeInc) {
|
||||
cc->geom.width -=
|
||||
(cc->geom.width - cc->geom.min_dx) % cc->size->width_inc;
|
||||
cc->geom.height -=
|
||||
(cc->geom.height - cc->geom.min_dy) % cc->size->height_inc;
|
||||
}
|
||||
|
||||
if (cc->size->flags & PMinSize) {
|
||||
cc->geom.width = MAX(cc->geom.width, cc->size->min_width);
|
||||
cc->geom.height = MAX(cc->geom.height, cc->size->min_height);
|
||||
}
|
||||
|
||||
if (cc->size->flags & PMaxSize) {
|
||||
cc->geom.width = MIN(cc->geom.width, cc->size->max_width);
|
||||
cc->geom.height = MIN(cc->geom.height, cc->size->max_height);
|
||||
}
|
||||
|
||||
cc->geom.x = x <= motionx ? x : x - cc->geom.width;
|
||||
cc->geom.y = y <= motiony ? y : y - cc->geom.height;
|
||||
|
||||
return (width != cc->geom.width || height != cc->geom.height);
|
||||
}
|
47
group.c
47
group.c
@@ -24,11 +24,22 @@
|
||||
|
||||
#define CALMWM_NGROUPS 9
|
||||
|
||||
static void _group_add(struct group_ctx *, struct client_ctx *);
|
||||
static void _group_remove(struct client_ctx *);
|
||||
static void _group_hide(struct group_ctx *);
|
||||
static void _group_show(struct group_ctx *);
|
||||
static void _group_fix_hidden_state(struct group_ctx *);
|
||||
|
||||
struct group_ctx *Group_active = NULL;
|
||||
struct group_ctx Groups[CALMWM_NGROUPS];
|
||||
int Grouphideall = 0;
|
||||
struct group_ctx_q Groupq;
|
||||
|
||||
const char *shortcut_to_name[] = {
|
||||
"nogroup", "one", "two", "three", "four", "five", "six",
|
||||
"seven", "eight", "nine"
|
||||
};
|
||||
|
||||
static void
|
||||
_group_add(struct group_ctx *gc, struct client_ctx *cc)
|
||||
{
|
||||
@@ -41,6 +52,9 @@ _group_add(struct group_ctx *gc, struct client_ctx *cc)
|
||||
if (cc->group != NULL)
|
||||
TAILQ_REMOVE(&cc->group->clients, cc, group_entry);
|
||||
|
||||
XChangeProperty(X_Dpy, cc->win, _CWM_GRP, XA_STRING,
|
||||
8, PropModeReplace, gc->name, strlen(gc->name));
|
||||
|
||||
TAILQ_INSERT_TAIL(&gc->clients, cc, group_entry);
|
||||
cc->group = gc;
|
||||
}
|
||||
@@ -51,6 +65,10 @@ _group_remove(struct client_ctx *cc)
|
||||
if (cc == NULL || cc->group == NULL)
|
||||
errx(1, "_group_remove: a ctx is NULL");
|
||||
|
||||
XChangeProperty(X_Dpy, cc->win, _CWM_GRP, XA_STRING, 8,
|
||||
PropModeReplace, shortcut_to_name[0],
|
||||
strlen(shortcut_to_name[0]));
|
||||
|
||||
TAILQ_REMOVE(&cc->group->clients, cc, group_entry);
|
||||
cc->group = NULL;
|
||||
}
|
||||
@@ -88,7 +106,7 @@ _group_show(struct group_ctx *gc)
|
||||
* top-to-bottom.
|
||||
*/
|
||||
TAILQ_FOREACH(cc, &gc->clients, group_entry) {
|
||||
winlist[gc->highstack - cc->stackingorder] = cc->pwin;
|
||||
winlist[gc->highstack - cc->stackingorder] = cc->win;
|
||||
client_unhide(cc);
|
||||
}
|
||||
|
||||
@@ -121,6 +139,7 @@ group_init(void)
|
||||
TAILQ_INIT(&Groups[i].clients);
|
||||
Groups[i].hidden = 0;
|
||||
Groups[i].shortcut = i + 1;
|
||||
Groups[i].name = shortcut_to_name[Groups[i].shortcut];
|
||||
TAILQ_INSERT_TAIL(&Groupq, &Groups[i], entry);
|
||||
}
|
||||
|
||||
@@ -156,12 +175,9 @@ group_sticky_toggle_exit(struct client_ctx *cc)
|
||||
}
|
||||
|
||||
/*
|
||||
* selection list display
|
||||
* if group_hidetoggle would produce no effect, toggle the group's hidden state
|
||||
*/
|
||||
|
||||
/* if group_hidetoggle would produce no effect, toggle the group's hidden state
|
||||
*/
|
||||
void
|
||||
static void
|
||||
_group_fix_hidden_state(struct group_ctx *gc)
|
||||
{
|
||||
struct client_ctx *cc;
|
||||
@@ -317,16 +333,23 @@ group_autogroup(struct client_ctx *cc)
|
||||
{
|
||||
struct autogroupwin *aw;
|
||||
struct group_ctx *gc;
|
||||
unsigned char *grpstr = NULL;
|
||||
char group[CALMWM_MAXNAMELEN];
|
||||
|
||||
if (cc->app_class == NULL || cc->app_name == NULL)
|
||||
return;
|
||||
|
||||
TAILQ_FOREACH(aw, &Conf.autogroupq, entry) {
|
||||
if (strcmp(aw->class, cc->app_class) == 0 &&
|
||||
(aw->name == NULL || strcmp(aw->name, cc->app_name) == 0)) {
|
||||
strlcpy(group, aw->group, sizeof(group));
|
||||
break;
|
||||
if (xu_getprop(cc, _CWM_GRP, XA_STRING,
|
||||
(CALMWM_MAXNAMELEN - 1)/sizeof(long), &grpstr) > 0) {
|
||||
strlcpy(group, grpstr, sizeof(group));
|
||||
XFree(grpstr);
|
||||
} else {
|
||||
TAILQ_FOREACH(aw, &Conf.autogroupq, entry) {
|
||||
if (strcmp(aw->class, cc->app_class) == 0 &&
|
||||
(aw->name == NULL ||
|
||||
strcmp(aw->name, cc->app_name) == 0)) {
|
||||
strlcpy(group, aw->group, sizeof(group));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -40,7 +40,8 @@
|
||||
#include <ctype.h>
|
||||
|
||||
#include <X11/cursorfont.h>
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/keysym.h>
|
||||
|
77
kbfunc.c
77
kbfunc.c
@@ -25,18 +25,17 @@
|
||||
|
||||
#define KNOWN_HOSTS ".ssh/known_hosts"
|
||||
#define HASH_MARKER "|1|"
|
||||
#define MOVE_AMOUNT 1
|
||||
|
||||
extern int _xev_quit;
|
||||
|
||||
void
|
||||
kbfunc_client_lower(struct client_ctx *cc, void *arg)
|
||||
kbfunc_client_lower(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
client_lower(cc);
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_client_raise(struct client_ctx *cc, void *arg)
|
||||
kbfunc_client_raise(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
client_raise(cc);
|
||||
}
|
||||
@@ -44,7 +43,7 @@ kbfunc_client_raise(struct client_ctx *cc, void *arg)
|
||||
#define typemask (CWM_MOVE | CWM_RESIZE | CWM_PTRMOVE)
|
||||
#define movemask (CWM_UP | CWM_DOWN | CWM_LEFT | CWM_RIGHT)
|
||||
void
|
||||
kbfunc_moveresize(struct client_ctx *cc, void *arg)
|
||||
kbfunc_moveresize(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
struct screen_ctx *sc;
|
||||
int x, y, flags, amt;
|
||||
@@ -53,8 +52,8 @@ kbfunc_moveresize(struct client_ctx *cc, void *arg)
|
||||
sc = screen_current();
|
||||
mx = my = 0;
|
||||
|
||||
flags = (int)arg;
|
||||
amt = MOVE_AMOUNT;
|
||||
flags = arg->i;
|
||||
amt = Conf.mamount;
|
||||
|
||||
if (flags & CWM_BIGMOVE) {
|
||||
flags -= CWM_BIGMOVE;
|
||||
@@ -80,17 +79,17 @@ kbfunc_moveresize(struct client_ctx *cc, void *arg)
|
||||
cc->geom.y += my;
|
||||
if (cc->geom.y + cc->geom.height < 0)
|
||||
cc->geom.y = -cc->geom.height;
|
||||
if (cc->geom.y > cc->sc->ymax)
|
||||
cc->geom.y = cc->sc->ymax;
|
||||
if (cc->geom.y > cc->sc->ymax - 1)
|
||||
cc->geom.y = cc->sc->ymax - 1;
|
||||
|
||||
cc->geom.x += mx;
|
||||
if (cc->geom.x + cc->geom.width < 0)
|
||||
cc->geom.x = -cc->geom.width;
|
||||
if (cc->geom.x > cc->sc->xmax)
|
||||
cc->geom.x = cc->sc->xmax;
|
||||
if (cc->geom.x > cc->sc->xmax - 1)
|
||||
cc->geom.x = cc->sc->xmax - 1;
|
||||
|
||||
client_move(cc);
|
||||
xu_ptr_getpos(cc->pwin, &x, &y);
|
||||
xu_ptr_getpos(cc->win, &x, &y);
|
||||
cc->ptr.y = y + my;
|
||||
cc->ptr.x = x + mx;
|
||||
client_ptrwarp(cc);
|
||||
@@ -103,7 +102,7 @@ kbfunc_moveresize(struct client_ctx *cc, void *arg)
|
||||
client_resize(cc);
|
||||
|
||||
/* Make sure the pointer stays within the window. */
|
||||
xu_ptr_getpos(cc->pwin, &cc->ptr.x, &cc->ptr.y);
|
||||
xu_ptr_getpos(cc->win, &cc->ptr.x, &cc->ptr.y);
|
||||
if (cc->ptr.x > cc->geom.width)
|
||||
cc->ptr.x = cc->geom.width - cc->bwidth;
|
||||
if (cc->ptr.y > cc->geom.height)
|
||||
@@ -112,8 +111,8 @@ kbfunc_moveresize(struct client_ctx *cc, void *arg)
|
||||
break;
|
||||
case CWM_PTRMOVE:
|
||||
if (cc) {
|
||||
xu_ptr_getpos(cc->pwin, &x, &y);
|
||||
xu_ptr_setpos(cc->pwin, 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);
|
||||
@@ -125,7 +124,7 @@ kbfunc_moveresize(struct client_ctx *cc, void *arg)
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_client_search(struct client_ctx *scratch, void *arg)
|
||||
kbfunc_client_search(struct client_ctx *scratch, union arg *arg)
|
||||
{
|
||||
struct client_ctx *cc, *old_cc;
|
||||
struct menu *mi;
|
||||
@@ -160,7 +159,7 @@ kbfunc_client_search(struct client_ctx *scratch, void *arg)
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_menu_search(struct client_ctx *scratch, void *arg)
|
||||
kbfunc_menu_search(struct client_ctx *scratch, union arg *arg)
|
||||
{
|
||||
struct cmd *cmd;
|
||||
struct menu *mi;
|
||||
@@ -186,7 +185,7 @@ kbfunc_menu_search(struct client_ctx *scratch, void *arg)
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_client_cycle(struct client_ctx *scratch, void *arg)
|
||||
kbfunc_client_cycle(struct client_ctx *scratch, union arg *arg)
|
||||
{
|
||||
struct screen_ctx *sc;
|
||||
|
||||
@@ -196,35 +195,35 @@ kbfunc_client_cycle(struct client_ctx *scratch, void *arg)
|
||||
XGrabKeyboard(X_Dpy, sc->rootwin, True,
|
||||
GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
|
||||
client_cycle((int)arg);
|
||||
client_cycle(arg->i);
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_client_hide(struct client_ctx *cc, void *arg)
|
||||
kbfunc_client_hide(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
client_hide(cc);
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_cmdexec(struct client_ctx *cc, void *arg)
|
||||
kbfunc_cmdexec(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
u_spawn((char *)arg);
|
||||
u_spawn(arg->c);
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_term(struct client_ctx *cc, void *arg)
|
||||
kbfunc_term(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
u_spawn(Conf.termpath);
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_lock(struct client_ctx *cc, void *arg)
|
||||
kbfunc_lock(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
u_spawn(Conf.lockpath);
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_exec(struct client_ctx *scratch, void *arg)
|
||||
kbfunc_exec(struct client_ctx *scratch, union arg *arg)
|
||||
{
|
||||
#define NPATHS 256
|
||||
char **ap, *paths[NPATHS], *path, *pathcpy, *label;
|
||||
@@ -238,7 +237,7 @@ kbfunc_exec(struct client_ctx *scratch, void *arg)
|
||||
struct menu_q menuq;
|
||||
struct stat sb;
|
||||
|
||||
int cmd = (int)arg;
|
||||
int cmd = arg->i;
|
||||
switch (cmd) {
|
||||
case CWM_EXEC_PROGRAM:
|
||||
label = "exec";
|
||||
@@ -338,7 +337,7 @@ kbfunc_exec(struct client_ctx *scratch, void *arg)
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_ssh(struct client_ctx *scratch, void *arg)
|
||||
kbfunc_ssh(struct client_ctx *scratch, union arg *arg)
|
||||
{
|
||||
struct menu *mi;
|
||||
struct menu_q menuq;
|
||||
@@ -405,7 +404,7 @@ kbfunc_ssh(struct client_ctx *scratch, void *arg)
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_client_label(struct client_ctx *cc, void *arg)
|
||||
kbfunc_client_label(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
struct menu *mi;
|
||||
struct menu_q menuq;
|
||||
@@ -428,59 +427,59 @@ kbfunc_client_label(struct client_ctx *cc, void *arg)
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_client_delete(struct client_ctx *cc, void *arg)
|
||||
kbfunc_client_delete(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
client_send_delete(cc);
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_client_group(struct client_ctx *cc, void *arg)
|
||||
kbfunc_client_group(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
group_hidetoggle(KBTOGROUP((int)arg));
|
||||
group_hidetoggle(KBTOGROUP(arg->i));
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_client_cyclegroup(struct client_ctx *cc, void *arg)
|
||||
kbfunc_client_cyclegroup(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
group_cycle((int)arg);
|
||||
group_cycle(arg->i);
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_client_nogroup(struct client_ctx *cc, void *arg)
|
||||
kbfunc_client_nogroup(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
group_alltoggle();
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_client_grouptoggle(struct client_ctx *cc, void *arg)
|
||||
kbfunc_client_grouptoggle(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
/* XXX for stupid X apps like xpdf and gvim */
|
||||
XGrabKeyboard(X_Dpy, cc->pwin, True,
|
||||
XGrabKeyboard(X_Dpy, cc->win, True,
|
||||
GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
|
||||
group_sticky_toggle_enter(cc);
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_client_maximize(struct client_ctx *cc, void *arg)
|
||||
kbfunc_client_maximize(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
client_maximize(cc);
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_client_vmaximize(struct client_ctx *cc, void *arg)
|
||||
kbfunc_client_vmaximize(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
client_vertmaximize(cc);
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_quit_wm(struct client_ctx *cc, void *arg)
|
||||
kbfunc_quit_wm(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
_xev_quit = 1;
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_reload(struct client_ctx *cc, void *arg)
|
||||
kbfunc_reload(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
conf_reload(&Conf);
|
||||
}
|
||||
|
144
mousefunc.c
144
mousefunc.c
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* calmwm - the calm window manager
|
||||
*
|
||||
* Copyright (c) 2004 Marius Aamodt Eriksen <marius@monkey.org>
|
||||
* Copyright (c) 2008 rivo nurges <rix@estpak.ee>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@@ -21,18 +22,153 @@
|
||||
#include "headers.h"
|
||||
#include "calmwm.h"
|
||||
|
||||
static int _mousefunc_sweep_calc(struct client_ctx *, int, int, int, int);
|
||||
static void _mousefunc_sweep_draw(struct client_ctx *, int, int);
|
||||
|
||||
#define ADJUST_HEIGHT(cc, dy) ((cc->geom.height - cc->geom.min_dy) / dy)
|
||||
#define ADJUST_WIDTH(cc, dx) ((cc->geom.width - cc->geom.min_dx) / dx)
|
||||
|
||||
static int
|
||||
_mousefunc_sweep_calc(struct client_ctx *cc, int x, int y, int mx, int my)
|
||||
{
|
||||
int width = cc->geom.width, height = cc->geom.height;
|
||||
|
||||
cc->geom.width = abs(x - mx) - cc->bwidth;
|
||||
cc->geom.height = abs(y - my) - cc->bwidth;
|
||||
|
||||
if (cc->size->flags & PResizeInc) {
|
||||
cc->geom.width -=
|
||||
(cc->geom.width - cc->geom.min_dx) % cc->size->width_inc;
|
||||
cc->geom.height -=
|
||||
(cc->geom.height - cc->geom.min_dy) % cc->size->height_inc;
|
||||
}
|
||||
|
||||
if (cc->size->flags & PMinSize) {
|
||||
cc->geom.width = MAX(cc->geom.width, cc->size->min_width);
|
||||
cc->geom.height = MAX(cc->geom.height, cc->size->min_height);
|
||||
}
|
||||
|
||||
if (cc->size->flags & PMaxSize) {
|
||||
cc->geom.width = MIN(cc->geom.width, cc->size->max_width);
|
||||
cc->geom.height = MIN(cc->geom.height, cc->size->max_height);
|
||||
}
|
||||
|
||||
cc->geom.x = x <= mx ? x : x - cc->geom.width;
|
||||
cc->geom.y = y <= my ? y : y - cc->geom.height;
|
||||
|
||||
return (width != cc->geom.width || height != cc->geom.height);
|
||||
}
|
||||
|
||||
static void
|
||||
_mousefunc_sweep_draw(struct client_ctx *cc, int dx, int dy)
|
||||
{
|
||||
struct screen_ctx *sc = CCTOSC(cc);
|
||||
char asize[10]; /* fits "nnnnxnnnn\0" */
|
||||
int wide, height, wide_size, wide_name;
|
||||
int x = cc->geom.x, y = cc->geom.y;
|
||||
|
||||
snprintf(asize, sizeof(asize), "%dx%d",
|
||||
ADJUST_WIDTH(cc, dx), ADJUST_HEIGHT(cc, dy));
|
||||
wide_size = font_width(asize, strlen(asize)) + 4;
|
||||
wide_name = font_width(cc->name, strlen(cc->name)) + 4;
|
||||
wide = MAX(wide_size, wide_name);
|
||||
height = font_ascent() + font_descent() + 1;
|
||||
|
||||
XMoveResizeWindow(X_Dpy, sc->menuwin, x, y, wide, height * 2);
|
||||
XMapWindow(X_Dpy, sc->menuwin);
|
||||
XReparentWindow(X_Dpy, sc->menuwin, cc->win, 0, 0);
|
||||
XClearWindow(X_Dpy, sc->menuwin);
|
||||
font_draw(sc, cc->name, strlen(cc->name), sc->menuwin,
|
||||
2, font_ascent() + 1);
|
||||
font_draw(sc, asize, strlen(asize), sc->menuwin,
|
||||
wide / 2 - wide_size / 2, height + font_ascent() + 1);
|
||||
}
|
||||
|
||||
void
|
||||
mousefunc_window_resize(struct client_ctx *cc, void *arg)
|
||||
{
|
||||
grab_sweep(cc);
|
||||
client_resize(cc);
|
||||
XEvent ev;
|
||||
struct screen_ctx *sc = CCTOSC(cc);
|
||||
int dx, dy;
|
||||
int x = cc->geom.x, y = cc->geom.y;
|
||||
|
||||
dx = MAX(1, cc->size->width_inc);
|
||||
dy = MAX(1, cc->size->height_inc);
|
||||
|
||||
client_raise(cc);
|
||||
client_ptrsave(cc);
|
||||
|
||||
if (xu_ptr_grab(sc->rootwin, MouseMask, Cursor_resize) < 0)
|
||||
return;
|
||||
|
||||
xu_ptr_setpos(cc->win, cc->geom.width, cc->geom.height);
|
||||
_mousefunc_sweep_draw(cc, dx, dy);
|
||||
|
||||
for (;;) {
|
||||
XMaskEvent(X_Dpy, MouseMask|ExposureMask, &ev);
|
||||
|
||||
switch (ev.type) {
|
||||
case Expose:
|
||||
client_draw_border(cc);
|
||||
break;
|
||||
case MotionNotify:
|
||||
if (_mousefunc_sweep_calc(cc, x, y,
|
||||
ev.xmotion.x, ev.xmotion.y))
|
||||
/* Recompute window output */
|
||||
_mousefunc_sweep_draw(cc, dx, dy);
|
||||
client_resize(cc);
|
||||
break;
|
||||
case ButtonRelease:
|
||||
XUnmapWindow(X_Dpy, sc->menuwin);
|
||||
XReparentWindow(X_Dpy, sc->menuwin, sc->rootwin, 0, 0);
|
||||
xu_ptr_ungrab();
|
||||
|
||||
/* Make sure the pointer stays within the window. */
|
||||
if (cc->ptr.x > cc->geom.width)
|
||||
cc->ptr.x = cc->geom.width - cc->bwidth;
|
||||
if (cc->ptr.y > cc->geom.height)
|
||||
cc->ptr.y = cc->geom.height - cc->bwidth;
|
||||
client_ptrwarp(cc);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
void
|
||||
mousefunc_window_move(struct client_ctx *cc, void *arg)
|
||||
{
|
||||
grab_drag(cc);
|
||||
client_move(cc);
|
||||
XEvent ev;
|
||||
struct screen_ctx *sc = CCTOSC(cc);
|
||||
int mx, my;
|
||||
int x = cc->geom.x, y = cc->geom.y;
|
||||
|
||||
client_raise(cc);
|
||||
|
||||
if (xu_ptr_grab(sc->rootwin, MouseMask, Cursor_move) < 0)
|
||||
return;
|
||||
|
||||
xu_ptr_getpos(sc->rootwin, &mx, &my);
|
||||
|
||||
for (;;) {
|
||||
XMaskEvent(X_Dpy, MouseMask|ExposureMask, &ev);
|
||||
|
||||
switch (ev.type) {
|
||||
case Expose:
|
||||
client_draw_border(cc);
|
||||
break;
|
||||
case MotionNotify:
|
||||
cc->geom.x = x + (ev.xmotion.x - mx);
|
||||
cc->geom.y = y + (ev.xmotion.y - my);
|
||||
client_move(cc);
|
||||
break;
|
||||
case ButtonRelease:
|
||||
xu_ptr_ungrab();
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
void
|
||||
|
68
parse.y
68
parse.y
@@ -54,8 +54,6 @@ int findeol(void);
|
||||
|
||||
static struct conf *conf;
|
||||
|
||||
extern char *shortcut_to_name[];
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
int64_t number;
|
||||
@@ -68,7 +66,7 @@ typedef struct {
|
||||
|
||||
%token FONTNAME STICKY GAP MOUSEBIND
|
||||
%token AUTOGROUP BIND COMMAND IGNORE
|
||||
%token YES NO
|
||||
%token YES NO BORDERWIDTH MOVEAMOUNT
|
||||
%token ERROR
|
||||
%token <v.string> STRING
|
||||
%token <v.number> NUMBER
|
||||
@@ -109,6 +107,12 @@ main : FONTNAME STRING {
|
||||
else
|
||||
conf->flags |= CONF_STICKY_GROUPS;
|
||||
}
|
||||
| BORDERWIDTH NUMBER {
|
||||
conf->bwidth = $2;
|
||||
}
|
||||
| MOVEAMOUNT NUMBER {
|
||||
conf->mamount = $2;
|
||||
}
|
||||
| COMMAND STRING string {
|
||||
conf_cmd_add(conf, $3, $2, 0);
|
||||
free($2);
|
||||
@@ -200,11 +204,13 @@ lookup(char *s)
|
||||
static const struct keywords keywords[] = {
|
||||
{ "autogroup", AUTOGROUP},
|
||||
{ "bind", BIND},
|
||||
{ "borderwidth", BORDERWIDTH},
|
||||
{ "command", COMMAND},
|
||||
{ "fontname", FONTNAME},
|
||||
{ "gap", GAP},
|
||||
{ "ignore", IGNORE},
|
||||
{ "mousebind", MOUSEBIND},
|
||||
{ "moveamount", MOVEAMOUNT},
|
||||
{ "no", NO},
|
||||
{ "sticky", STICKY},
|
||||
{ "yes", YES}
|
||||
@@ -462,50 +468,6 @@ popfile(void)
|
||||
return (EOF);
|
||||
}
|
||||
|
||||
void
|
||||
conf_clear(struct conf *c)
|
||||
{
|
||||
struct autogroupwin *ag;
|
||||
struct keybinding *kb;
|
||||
struct winmatch *wm;
|
||||
struct cmd *cmd;
|
||||
struct mousebinding *mb;
|
||||
|
||||
while (cmd = TAILQ_FIRST(&c->cmdq)) {
|
||||
TAILQ_REMOVE(&c->cmdq, cmd, entry);
|
||||
free(cmd);
|
||||
}
|
||||
|
||||
while (kb = TAILQ_FIRST(&c->keybindingq)) {
|
||||
TAILQ_REMOVE(&c->keybindingq, kb, entry);
|
||||
free(kb);
|
||||
}
|
||||
|
||||
while (ag = TAILQ_FIRST(&c->autogroupq)) {
|
||||
TAILQ_REMOVE(&c->autogroupq, ag, entry);
|
||||
free(ag->class);
|
||||
if (ag->name)
|
||||
free(ag->name);
|
||||
free(ag->group);
|
||||
free(ag);
|
||||
}
|
||||
|
||||
while (wm = TAILQ_FIRST(&c->ignoreq)) {
|
||||
TAILQ_REMOVE(&c->ignoreq, wm, entry);
|
||||
free(wm);
|
||||
}
|
||||
|
||||
while (mb = TAILQ_FIRST(&c->mousebindingq)) {
|
||||
TAILQ_REMOVE(&c->mousebindingq, mb, entry);
|
||||
free(mb);
|
||||
}
|
||||
|
||||
if (c->DefaultFontName != NULL &&
|
||||
c->DefaultFontName != DEFAULTFONTNAME)
|
||||
free(c->DefaultFontName);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
parse_config(const char *filename, struct conf *xconf)
|
||||
{
|
||||
@@ -540,28 +502,30 @@ parse_config(const char *filename, struct conf *xconf)
|
||||
conf_clear(xconf);
|
||||
|
||||
xconf->flags = conf->flags;
|
||||
xconf->bwidth = conf->bwidth;
|
||||
xconf->mamount = conf->mamount;
|
||||
|
||||
while (cmd = TAILQ_FIRST(&conf->cmdq)) {
|
||||
while ((cmd = TAILQ_FIRST(&conf->cmdq)) != NULL) {
|
||||
TAILQ_REMOVE(&conf->cmdq, cmd, entry);
|
||||
TAILQ_INSERT_TAIL(&xconf->cmdq, cmd, entry);
|
||||
}
|
||||
|
||||
while (kb = TAILQ_FIRST(&conf->keybindingq)) {
|
||||
while ((kb = TAILQ_FIRST(&conf->keybindingq)) != NULL) {
|
||||
TAILQ_REMOVE(&conf->keybindingq, kb, entry);
|
||||
TAILQ_INSERT_TAIL(&xconf->keybindingq, kb, entry);
|
||||
}
|
||||
|
||||
while (ag = TAILQ_FIRST(&conf->autogroupq)) {
|
||||
while ((ag = TAILQ_FIRST(&conf->autogroupq)) != NULL) {
|
||||
TAILQ_REMOVE(&conf->autogroupq, ag, entry);
|
||||
TAILQ_INSERT_TAIL(&xconf->autogroupq, ag, entry);
|
||||
}
|
||||
|
||||
while (wm = TAILQ_FIRST(&conf->ignoreq)) {
|
||||
while ((wm = TAILQ_FIRST(&conf->ignoreq)) != NULL) {
|
||||
TAILQ_REMOVE(&conf->ignoreq, wm, entry);
|
||||
TAILQ_INSERT_TAIL(&xconf->ignoreq, wm, entry);
|
||||
}
|
||||
|
||||
while (mb = TAILQ_FIRST(&conf->mousebindingq)) {
|
||||
while ((mb = TAILQ_FIRST(&conf->mousebindingq)) != NULL) {
|
||||
TAILQ_REMOVE(&conf->mousebindingq, mb, entry);
|
||||
TAILQ_INSERT_TAIL(&xconf->mousebindingq, mb, entry);
|
||||
}
|
||||
|
43
screen.c
43
screen.c
@@ -67,3 +67,46 @@ screen_updatestackingorder(void)
|
||||
|
||||
XFree(wins);
|
||||
}
|
||||
|
||||
void
|
||||
screen_init_xinerama(struct screen_ctx *sc)
|
||||
{
|
||||
XineramaScreenInfo *info;
|
||||
int no;
|
||||
|
||||
if (HasXinerama == 0 || XineramaIsActive(X_Dpy) == 0) {
|
||||
HasXinerama = 0;
|
||||
sc->xinerama_no = 0;
|
||||
}
|
||||
|
||||
info = XineramaQueryScreens(X_Dpy, &no);
|
||||
if (info == NULL) {
|
||||
/*is xinerama is actually off, instead of a malloc failure? */
|
||||
if (sc->xinerama == NULL)
|
||||
HasXinerama = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (sc->xinerama != NULL)
|
||||
XFree(sc->xinerama);
|
||||
sc->xinerama = info;
|
||||
sc->xinerama_no = no;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find which xinerama screen the coordinates (x,y) is on.
|
||||
*/
|
||||
XineramaScreenInfo *
|
||||
screen_find_xinerama(struct screen_ctx *sc, int x, int y)
|
||||
{
|
||||
XineramaScreenInfo *info;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sc->xinerama_no; i++) {
|
||||
info = &sc->xinerama[i];
|
||||
if (x > info->x_org && x < info->x_org + info->width &&
|
||||
y > info->y_org && y < info->y_org + info->height)
|
||||
return (info);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
18
search.c
18
search.c
@@ -132,7 +132,7 @@ search_print_client(struct menu *mi, int list)
|
||||
flag = '&';
|
||||
|
||||
if (list)
|
||||
cc->matchname = TAILQ_FIRST(&cc->nameq)->name;
|
||||
cc->matchname = cc->name;
|
||||
|
||||
snprintf(mi->print, sizeof(mi->print), "%c%s", flag, cc->matchname);
|
||||
|
||||
@@ -175,13 +175,23 @@ search_match_text(struct menu_q *menuq, struct menu_q *resultq, char *search)
|
||||
void
|
||||
search_match_exec(struct menu_q *menuq, struct menu_q *resultq, char *search)
|
||||
{
|
||||
struct menu *mi;
|
||||
struct menu *mi, *mj;
|
||||
|
||||
TAILQ_INIT(resultq);
|
||||
|
||||
TAILQ_FOREACH(mi, menuq, entry)
|
||||
if (_strsubmatch(search, mi->text, 1))
|
||||
TAILQ_FOREACH(mi, menuq, entry) {
|
||||
if (_strsubmatch(search, mi->text, 1) == 0)
|
||||
continue;
|
||||
for (mj = TAILQ_FIRST(resultq); mj != NULL;
|
||||
mj = TAILQ_NEXT(mj, resultentry)) {
|
||||
if (strcasecmp(mi->text, mj->text) < 0) {
|
||||
TAILQ_INSERT_BEFORE(mj, mi, resultentry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mj == NULL)
|
||||
TAILQ_INSERT_TAIL(resultq, mi, resultentry);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
127
xevents.c
127
xevents.c
@@ -36,13 +36,8 @@ void
|
||||
xev_handle_maprequest(struct xevent *xev, XEvent *ee)
|
||||
{
|
||||
XMapRequestEvent *e = &ee->xmaprequest;
|
||||
XWindowAttributes xattr;
|
||||
struct client_ctx *cc = NULL, *old_cc;
|
||||
struct screen_ctx *sc;
|
||||
|
||||
#ifdef notyet
|
||||
int state;
|
||||
#endif
|
||||
XWindowAttributes xattr;
|
||||
|
||||
if ((old_cc = client_current()) != NULL)
|
||||
client_ptrsave(old_cc);
|
||||
@@ -50,15 +45,7 @@ xev_handle_maprequest(struct xevent *xev, XEvent *ee)
|
||||
if ((cc = client_find(e->window)) == NULL) {
|
||||
XGetWindowAttributes(X_Dpy, e->window, &xattr);
|
||||
cc = client_new(e->window, screen_fromroot(xattr.root), 1);
|
||||
sc = CCTOSC(cc);
|
||||
} else
|
||||
cc->beepbeep = 1;
|
||||
|
||||
#ifdef notyet /* XXX - possibly, we shouldn't map if
|
||||
* the window is withdrawn. */
|
||||
if (xu_getstate(cc, &state) == 0 && state == WithdrawnState)
|
||||
warnx("WITHDRAWNSTATE for %s", cc->name);
|
||||
#endif
|
||||
}
|
||||
|
||||
client_ptrwarp(cc);
|
||||
xev_register(xev);
|
||||
@@ -68,10 +55,27 @@ void
|
||||
xev_handle_unmapnotify(struct xevent *xev, XEvent *ee)
|
||||
{
|
||||
XUnmapEvent *e = &ee->xunmap;
|
||||
XEvent ev;
|
||||
struct client_ctx *cc;
|
||||
|
||||
if ((cc = client_find(e->window)) != NULL)
|
||||
client_delete(cc, e->send_event, 0);
|
||||
/* XXX, we need a recursive locking wrapper around grab server */
|
||||
XGrabServer(X_Dpy);
|
||||
if ((cc = client_find(e->window)) != NULL) {
|
||||
/*
|
||||
* If it's going to die anyway, nuke it.
|
||||
*
|
||||
* Else, if it's a synthetic event delete state, since they
|
||||
* want it to be withdrawn. ICCM recommends you withdraw on
|
||||
* this even if we haven't alredy been told to iconify, to
|
||||
* deal with legacy clients.
|
||||
*/
|
||||
if (XCheckTypedWindowEvent(X_Dpy, cc->win,
|
||||
DestroyNotify, &ev) || e->send_event != 0) {
|
||||
client_delete(cc);
|
||||
} else
|
||||
client_hide(cc);
|
||||
}
|
||||
XUngrabServer(X_Dpy);
|
||||
|
||||
xev_register(xev);
|
||||
}
|
||||
@@ -83,7 +87,7 @@ xev_handle_destroynotify(struct xevent *xev, XEvent *ee)
|
||||
struct client_ctx *cc;
|
||||
|
||||
if ((cc = client_find(e->window)) != NULL)
|
||||
client_delete(cc, 1, 1);
|
||||
client_delete(cc);
|
||||
|
||||
xev_register(xev);
|
||||
}
|
||||
@@ -99,7 +103,6 @@ xev_handle_configurerequest(struct xevent *xev, XEvent *ee)
|
||||
if ((cc = client_find(e->window)) != NULL) {
|
||||
sc = CCTOSC(cc);
|
||||
|
||||
client_gravitate(cc, 0);
|
||||
if (e->value_mask & CWWidth)
|
||||
cc->geom.width = e->width;
|
||||
if (e->value_mask & CWHeight)
|
||||
@@ -108,39 +111,36 @@ xev_handle_configurerequest(struct xevent *xev, XEvent *ee)
|
||||
cc->geom.x = e->x;
|
||||
if (e->value_mask & CWY)
|
||||
cc->geom.y = e->y;
|
||||
if (e->value_mask & CWBorderWidth)
|
||||
wc.border_width = e->border_width;
|
||||
|
||||
if (cc->geom.x == 0 &&
|
||||
cc->geom.width >= DisplayWidth(X_Dpy, sc->which))
|
||||
if (cc->geom.x == 0 && cc->geom.width >= sc->xmax)
|
||||
cc->geom.x -= cc->bwidth;
|
||||
|
||||
if (cc->geom.y == 0 &&
|
||||
cc->geom.height >= DisplayHeight(X_Dpy, sc->which))
|
||||
if (cc->geom.y == 0 && cc->geom.height >= sc->ymax)
|
||||
cc->geom.y -= cc->bwidth;
|
||||
|
||||
client_gravitate(cc, 1);
|
||||
wc.x = cc->geom.x;
|
||||
wc.y = cc->geom.y;
|
||||
wc.width = cc->geom.width;
|
||||
wc.height = cc->geom.height;
|
||||
wc.border_width = cc->bwidth;
|
||||
|
||||
wc.x = cc->geom.x - cc->bwidth;
|
||||
wc.y = cc->geom.y - cc->bwidth;
|
||||
wc.width = cc->geom.width + cc->bwidth*2;
|
||||
wc.height = cc->geom.height + cc->bwidth*2;
|
||||
wc.border_width = 0;
|
||||
|
||||
/* We need to move the parent window, too. */
|
||||
XConfigureWindow(X_Dpy, cc->pwin, e->value_mask, &wc);
|
||||
XConfigureWindow(X_Dpy, cc->win, e->value_mask, &wc);
|
||||
xev_reconfig(cc);
|
||||
} else {
|
||||
/* let it do what it wants, it'll be ours when we map it. */
|
||||
wc.x = e->x;
|
||||
wc.y = e->y;
|
||||
wc.width = e->width;
|
||||
wc.height = e->height;
|
||||
wc.border_width = e->border_width;
|
||||
wc.stack_mode = Above;
|
||||
e->value_mask &= ~CWStackMode;
|
||||
|
||||
XConfigureWindow(X_Dpy, e->window, e->value_mask, &wc);
|
||||
}
|
||||
|
||||
wc.x = cc != NULL ? cc->bwidth : e->x;
|
||||
wc.y = cc != NULL ? cc->bwidth : e->y;
|
||||
wc.width = e->width;
|
||||
wc.height = e->height;
|
||||
wc.stack_mode = Above;
|
||||
wc.border_width = 0;
|
||||
e->value_mask &= ~CWStackMode;
|
||||
e->value_mask |= CWBorderWidth;
|
||||
|
||||
XConfigureWindow(X_Dpy, e->window, e->value_mask, &wc);
|
||||
|
||||
xev_register(xev);
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ xev_reconfig(struct client_ctx *cc)
|
||||
ce.y = cc->geom.y;
|
||||
ce.width = cc->geom.width;
|
||||
ce.height = cc->geom.height;
|
||||
ce.border_width = 0;
|
||||
ce.border_width = cc->bwidth;
|
||||
ce.above = None;
|
||||
ce.override_redirect = 0;
|
||||
|
||||
@@ -193,17 +193,7 @@ xev_handle_enternotify(struct xevent *xev, XEvent *ee)
|
||||
XCrossingEvent *e = &ee->xcrossing;
|
||||
struct client_ctx *cc;
|
||||
|
||||
if ((cc = client_find(e->window)) == NULL) {
|
||||
/*
|
||||
* XXX - later. messes up unclutter. but may be
|
||||
* needed when we introduce menu windows and such into
|
||||
* the main event loop.
|
||||
*/
|
||||
#ifdef notyet
|
||||
if (e->window != e->root)
|
||||
client_nocurrent();
|
||||
#endif
|
||||
} else
|
||||
if ((cc = client_find(e->window)) != NULL)
|
||||
client_setactive(cc, 1);
|
||||
|
||||
xev_register(xev);
|
||||
@@ -225,7 +215,6 @@ xev_handle_buttonpress(struct xevent *xev, XEvent *ee)
|
||||
struct client_ctx *cc;
|
||||
struct screen_ctx *sc;
|
||||
struct mousebinding *mb;
|
||||
char *wname;
|
||||
|
||||
sc = screen_fromroot(e->root);
|
||||
cc = client_find(e->window);
|
||||
@@ -305,7 +294,7 @@ xev_handle_keypress(struct xevent *xev, XEvent *ee)
|
||||
if (kb->flags & KBFLAG_NEEDCLIENT)
|
||||
goto out;
|
||||
|
||||
(*kb->callback)(cc, kb->argument);
|
||||
(*kb->callback)(cc, &kb->argument);
|
||||
|
||||
out:
|
||||
xev_register(xev);
|
||||
@@ -366,13 +355,19 @@ out:
|
||||
}
|
||||
|
||||
void
|
||||
xev_handle_shape(struct xevent *xev, XEvent *ee)
|
||||
xev_handle_randr(struct xevent *xev, XEvent *ee)
|
||||
{
|
||||
XShapeEvent *sev = (XShapeEvent *) ee;
|
||||
struct client_ctx *cc;
|
||||
XRRScreenChangeNotifyEvent *rev = (XRRScreenChangeNotifyEvent *)ee;
|
||||
struct client_ctx *cc;
|
||||
struct screen_ctx *sc;
|
||||
|
||||
if ((cc = client_find(sev->window)) != NULL)
|
||||
client_do_shape(cc);
|
||||
if ((cc = client_find(rev->window)) != NULL) {
|
||||
XRRUpdateConfiguration(ee);
|
||||
sc = CCTOSC(cc);
|
||||
sc->xmax = rev->width;
|
||||
sc->ymax = rev->height;
|
||||
screen_init_xinerama(sc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -453,10 +448,8 @@ xev_handle_expose(struct xevent *xev, XEvent *ee)
|
||||
XExposeEvent *e = &ee->xexpose;
|
||||
struct client_ctx *cc;
|
||||
|
||||
if ((cc = client_find(e->window)) != NULL && e->count == 0) {
|
||||
if ((cc = client_find(e->window)) != NULL && e->count == 0)
|
||||
client_draw_border(cc);
|
||||
client_do_shape(cc);
|
||||
}
|
||||
|
||||
xev_register(xev);
|
||||
}
|
||||
@@ -523,8 +516,8 @@ xev_loop(void)
|
||||
ASSIGN1(xclient);
|
||||
break;
|
||||
default:
|
||||
if (e.type == Shape_ev)
|
||||
xev_handle_shape(xev, &e);
|
||||
if (e.type == Randr_ev)
|
||||
xev_handle_randr(xev, &e);
|
||||
break;
|
||||
}
|
||||
|
||||
|
27
xutil.c
27
xutil.c
@@ -145,12 +145,9 @@ xu_getprop(struct client_ctx *cc, Atom atm, Atom type, long len, u_char **p)
|
||||
int
|
||||
xu_getstate(struct client_ctx *cc, int *state)
|
||||
{
|
||||
Atom wm_state;
|
||||
long *p = NULL;
|
||||
|
||||
wm_state = XInternAtom(X_Dpy, "WM_STATE", False);
|
||||
|
||||
if (xu_getprop(cc, wm_state, wm_state, 2L, (u_char **)&p) <= 0)
|
||||
if (xu_getprop(cc, WM_STATE, WM_STATE, 2L, (u_char **)&p) <= 0)
|
||||
return (-1);
|
||||
|
||||
*state = (int)*p;
|
||||
@@ -162,16 +159,28 @@ xu_getstate(struct client_ctx *cc, int *state)
|
||||
void
|
||||
xu_setstate(struct client_ctx *cc, int state)
|
||||
{
|
||||
Atom wm_state;
|
||||
long dat[2];
|
||||
|
||||
/* XXX cache */
|
||||
wm_state = XInternAtom(X_Dpy, "WM_STATE", False);
|
||||
|
||||
dat[0] = (long)state;
|
||||
dat[1] = (long)None;
|
||||
|
||||
cc->state = state;
|
||||
XChangeProperty(X_Dpy, cc->win, wm_state, wm_state, 32,
|
||||
XChangeProperty(X_Dpy, cc->win, WM_STATE, WM_STATE, 32,
|
||||
PropModeReplace, (unsigned char *)dat, 2);
|
||||
}
|
||||
|
||||
Atom cwm_atoms[CWM_NO_ATOMS];
|
||||
char *atoms[CWM_NO_ATOMS] = {
|
||||
"WM_STATE",
|
||||
"WM_DELETE_WINDOW",
|
||||
"WM_TAKE_FOCUS",
|
||||
"WM_PROTOCOLS",
|
||||
"_MOTIF_WM_HINTS",
|
||||
"_CWM_GRP",
|
||||
};
|
||||
|
||||
void
|
||||
xu_getatoms(void)
|
||||
{
|
||||
XInternAtoms(X_Dpy, atoms, CWM_NO_ATOMS, False, cwm_atoms);
|
||||
}
|
||||
|
Reference in New Issue
Block a user