Unrelated style fixes, consistency changes and sorting, appropriate

dosage/removal of wrappers, simplification of name queue, client cycle joins
other kb/mb bound functions.
This commit is contained in:
okan 2020-02-27 14:56:39 +00:00
parent 7a88b2bdb2
commit 96275a835d
13 changed files with 463 additions and 444 deletions

View File

@ -44,6 +44,7 @@ struct screen_q Screenq = TAILQ_HEAD_INITIALIZER(Screenq);
struct conf Conf; struct conf Conf;
volatile sig_atomic_t cwm_status; volatile sig_atomic_t cwm_status;
__dead void usage(void);
static void sighdlr(int); static void sighdlr(int);
static int x_errorhandler(Display *, XErrorEvent *); static int x_errorhandler(Display *, XErrorEvent *);
static int x_init(const char *); static int x_init(const char *);
@ -124,7 +125,7 @@ main(int argc, char **argv)
u_exec(fallback); u_exec(fallback);
} }
return(0); return 0;
} }
static int static int
@ -142,7 +143,7 @@ x_init(const char *dpyname)
Conf.xrandr = XRRQueryExtension(X_Dpy, &Conf.xrandr_event_base, &i); Conf.xrandr = XRRQueryExtension(X_Dpy, &Conf.xrandr_event_base, &i);
conf_atoms(); xu_atom_init();
conf_cursor(&Conf); conf_cursor(&Conf);
for (i = 0; i < ScreenCount(X_Dpy); i++) for (i = 0; i < ScreenCount(X_Dpy); i++)
@ -180,7 +181,7 @@ static int
x_wmerrorhandler(Display *dpy, XErrorEvent *e) x_wmerrorhandler(Display *dpy, XErrorEvent *e)
{ {
errx(1, "root window unavailable - perhaps another wm is running?"); errx(1, "root window unavailable - perhaps another wm is running?");
return(0); return 0;
} }
static int static int
@ -196,7 +197,7 @@ x_errorhandler(Display *dpy, XErrorEvent *e)
warnx("%s(0x%x): %s", req, (unsigned int)e->resourceid, msg); warnx("%s(0x%x): %s", req, (unsigned int)e->resourceid, msg);
#endif #endif
return(0); return 0;
} }
static void static void

View File

@ -63,7 +63,6 @@
#define CWM_UP_LEFT (CWM_UP | CWM_LEFT) #define CWM_UP_LEFT (CWM_UP | CWM_LEFT)
#define CWM_DOWN_RIGHT (CWM_DOWN | CWM_RIGHT) #define CWM_DOWN_RIGHT (CWM_DOWN | CWM_RIGHT)
#define CWM_DOWN_LEFT (CWM_DOWN | CWM_LEFT) #define CWM_DOWN_LEFT (CWM_DOWN | CWM_LEFT)
#define DIRECTIONMASK (CWM_UP | CWM_DOWN | CWM_LEFT | CWM_RIGHT)
#define CWM_CYCLE_FORWARD 0x0001 #define CWM_CYCLE_FORWARD 0x0001
#define CWM_CYCLE_REVERSE 0x0002 #define CWM_CYCLE_REVERSE 0x0002
@ -100,11 +99,6 @@ struct geom {
int w; int w;
int h; int h;
}; };
enum apply_gap {
CWM_NOGAP = 0,
CWM_GAP
};
struct gap { struct gap {
int top; int top;
int bottom; int bottom;
@ -176,8 +170,9 @@ struct client_ctx {
struct name_q nameq; struct name_q nameq;
char *name; char *name;
char *label; char *label;
XClassHint ch; char *res_class; /* class hint */
XWMHints *wmh; char *res_name; /* class hint */
int initial_state; /* wm hint */
}; };
TAILQ_HEAD(client_q, client_ctx); TAILQ_HEAD(client_q, client_ctx);
@ -390,40 +385,36 @@ extern Atom ewmh[EWMH_NITEMS];
extern struct screen_q Screenq; extern struct screen_q Screenq;
extern struct conf Conf; extern struct conf Conf;
__dead void usage(void); void client_apply_sizehints(struct client_ctx *);
void client_close(struct client_ctx *);
void client_applysizehints(struct client_ctx *);
void client_config(struct client_ctx *); void client_config(struct client_ctx *);
struct client_ctx *client_current(struct screen_ctx *); struct client_ctx *client_current(struct screen_ctx *);
void client_cycle(struct screen_ctx *, int);
void client_remove(struct client_ctx *);
void client_draw_border(struct client_ctx *); void client_draw_border(struct client_ctx *);
struct client_ctx *client_find(Window); struct client_ctx *client_find(Window);
long client_get_wm_state(struct client_ctx *); void client_get_sizehints(struct client_ctx *);
void client_getsizehints(struct client_ctx *);
void client_hide(struct client_ctx *); void client_hide(struct client_ctx *);
void client_htile(struct client_ctx *); void client_htile(struct client_ctx *);
void client_lower(struct client_ctx *);
void client_msg(struct client_ctx *, Atom, Time);
void client_move(struct client_ctx *);
void client_mtf(struct client_ctx *);
int client_inbound(struct client_ctx *, int, int); int client_inbound(struct client_ctx *, int, int);
struct client_ctx *client_init(Window, struct screen_ctx *, int); struct client_ctx *client_init(Window, struct screen_ctx *, int);
void client_lower(struct client_ctx *);
void client_move(struct client_ctx *);
void client_mtf(struct client_ctx *);
struct client_ctx *client_next(struct client_ctx *);
struct client_ctx *client_prev(struct client_ctx *);
void client_ptr_inbound(struct client_ctx *, int); void client_ptr_inbound(struct client_ctx *, int);
void client_ptrsave(struct client_ctx *); void client_ptr_save(struct client_ctx *);
void client_ptrwarp(struct client_ctx *); void client_ptr_warp(struct client_ctx *);
void client_raise(struct client_ctx *); void client_raise(struct client_ctx *);
void client_remove(struct client_ctx *);
void client_resize(struct client_ctx *, int); void client_resize(struct client_ctx *, int);
void client_close(struct client_ctx *); void client_set_active(struct client_ctx *);
void client_set_wm_state(struct client_ctx *, long); void client_set_name(struct client_ctx *);
void client_setactive(struct client_ctx *);
void client_setname(struct client_ctx *);
void client_show(struct client_ctx *); void client_show(struct client_ctx *);
int client_snapcalc(int, int, int, int, int); int client_snapcalc(int, int, int, int, int);
void client_toggle_freeze(struct client_ctx *);
void client_toggle_fullscreen(struct client_ctx *);
void client_toggle_hidden(struct client_ctx *); void client_toggle_hidden(struct client_ctx *);
void client_toggle_hmaximize(struct client_ctx *); void client_toggle_hmaximize(struct client_ctx *);
void client_toggle_fullscreen(struct client_ctx *);
void client_toggle_freeze(struct client_ctx *);
void client_toggle_maximize(struct client_ctx *); void client_toggle_maximize(struct client_ctx *);
void client_toggle_skip_pager(struct client_ctx *); void client_toggle_skip_pager(struct client_ctx *);
void client_toggle_skip_taskbar(struct client_ctx *); void client_toggle_skip_taskbar(struct client_ctx *);
@ -453,16 +444,16 @@ void group_update_names(struct screen_ctx *);
void search_match_client(struct menu_q *, struct menu_q *, void search_match_client(struct menu_q *, struct menu_q *,
char *); char *);
void search_match_cmd(struct menu_q *, struct menu_q *,
char *);
void search_match_exec(struct menu_q *, struct menu_q *, void search_match_exec(struct menu_q *, struct menu_q *,
char *); char *);
void search_match_group(struct menu_q *, struct menu_q *,
char *);
void search_match_path(struct menu_q *, struct menu_q *, void search_match_path(struct menu_q *, struct menu_q *,
char *); char *);
void search_match_text(struct menu_q *, struct menu_q *, void search_match_text(struct menu_q *, struct menu_q *,
char *); char *);
void search_match_cmd(struct menu_q *, struct menu_q *,
char *);
void search_match_group(struct menu_q *, struct menu_q *,
char *);
void search_match_wm(struct menu_q *, struct menu_q *, void search_match_wm(struct menu_q *, struct menu_q *,
char *); char *);
void search_print_client(struct menu *, int); void search_print_client(struct menu *, int);
@ -472,19 +463,18 @@ void search_print_text(struct menu *, int);
void search_print_wm(struct menu *, int); void search_print_wm(struct menu *, int);
struct region_ctx *region_find(struct screen_ctx *, int, int); struct region_ctx *region_find(struct screen_ctx *, int, int);
struct screen_ctx *screen_find(Window);
struct geom screen_area(struct screen_ctx *, int, int,
enum apply_gap);
void screen_init(int);
void screen_update_geometry(struct screen_ctx *);
void screen_updatestackingorder(struct screen_ctx *);
void screen_assert_clients_within(struct screen_ctx *); void screen_assert_clients_within(struct screen_ctx *);
struct geom screen_area(struct screen_ctx *, int, int, int);
struct screen_ctx *screen_find(Window);
void screen_init(int);
void screen_prop_win_create(struct screen_ctx *, Window); void screen_prop_win_create(struct screen_ctx *, Window);
void screen_prop_win_destroy(struct screen_ctx *); void screen_prop_win_destroy(struct screen_ctx *);
void screen_prop_win_draw(struct screen_ctx *, void screen_prop_win_draw(struct screen_ctx *,
const char *, ...) const char *, ...)
__attribute__((__format__ (printf, 2, 3))) __attribute__((__format__ (printf, 2, 3)))
__attribute__((__nonnull__ (2))); __attribute__((__nonnull__ (2)));
void screen_update_geometry(struct screen_ctx *);
void screen_updatestackingorder(struct screen_ctx *);
void kbfunc_cwm_status(void *, struct cargs *); void kbfunc_cwm_status(void *, struct cargs *);
void kbfunc_ptrmove(void *, struct cargs *); void kbfunc_ptrmove(void *, struct cargs *);
@ -533,7 +523,6 @@ void menuq_clear(struct menu_q *);
int parse_config(const char *, struct conf *); int parse_config(const char *, struct conf *);
void conf_atoms(void);
void conf_autogroup(struct conf *, int, const char *, void conf_autogroup(struct conf *, int, const char *,
const char *); const char *);
int conf_bind_key(struct conf *, const char *, int conf_bind_key(struct conf *, const char *,
@ -556,12 +545,16 @@ void conf_group(struct screen_ctx *);
void xev_process(void); void xev_process(void);
int xu_getprop(Window, Atom, Atom, long, unsigned char **); int xu_get_prop(Window, Atom, Atom, long, unsigned char **);
int xu_getstrprop(Window, Atom, char **); int xu_get_strprop(Window, Atom, char **);
void xu_ptr_getpos(Window, int *, int *); void xu_ptr_get(Window, int *, int *);
void xu_ptr_setpos(Window, int, int); void xu_ptr_set(Window, int, int);
void xu_get_wm_state(Window, long *);
void xu_set_wm_state(Window, long);
void xu_send_clientmsg(Window, Atom, Time);
void xu_xorcolor(XftColor, XftColor, XftColor *); void xu_xorcolor(XftColor, XftColor, XftColor *);
void xu_atom_init(void);
void xu_ewmh_net_supported(struct screen_ctx *); void xu_ewmh_net_supported(struct screen_ctx *);
void xu_ewmh_net_supported_wm_check(struct screen_ctx *); void xu_ewmh_net_supported_wm_check(struct screen_ctx *);
void xu_ewmh_net_desktop_geometry(struct screen_ctx *); void xu_ewmh_net_desktop_geometry(struct screen_ctx *);
@ -576,8 +569,8 @@ void xu_ewmh_net_showing_desktop(struct screen_ctx *);
void xu_ewmh_net_virtual_roots(struct screen_ctx *); void xu_ewmh_net_virtual_roots(struct screen_ctx *);
void xu_ewmh_net_current_desktop(struct screen_ctx *); void xu_ewmh_net_current_desktop(struct screen_ctx *);
void xu_ewmh_net_desktop_names(struct screen_ctx *); void xu_ewmh_net_desktop_names(struct screen_ctx *);
int xu_ewmh_get_net_wm_desktop(struct client_ctx *, long *);
void xu_ewmh_net_wm_desktop(struct client_ctx *); void xu_ewmh_set_net_wm_desktop(struct client_ctx *);
Atom *xu_ewmh_get_net_wm_state(struct client_ctx *, int *); Atom *xu_ewmh_get_net_wm_state(struct client_ctx *, int *);
void xu_ewmh_handle_net_wm_state_msg(struct client_ctx *, void xu_ewmh_handle_net_wm_state_msg(struct client_ctx *,
int, Atom , Atom); int, Atom , Atom);

353
client.c
View File

@ -31,11 +31,10 @@
#include "calmwm.h" #include "calmwm.h"
static struct client_ctx *client_next(struct client_ctx *); static void client_class_hint(struct client_ctx *);
static struct client_ctx *client_prev(struct client_ctx *); static void client_placement(struct client_ctx *);
static void client_placecalc(struct client_ctx *);
static void client_wm_protocols(struct client_ctx *);
static void client_mwm_hints(struct client_ctx *); static void client_mwm_hints(struct client_ctx *);
static void client_wm_protocols(struct client_ctx *);
struct client_ctx * struct client_ctx *
client_init(Window win, struct screen_ctx *sc, int active) client_init(Window win, struct screen_ctx *sc, int active)
@ -46,19 +45,20 @@ client_init(Window win, struct screen_ctx *sc, int active)
Window rwin, cwin; Window rwin, cwin;
int x, y, wx, wy; int x, y, wx, wy;
unsigned int mask; unsigned int mask;
long state;
if (win == None) if (win == None)
return(NULL); return NULL;
if (!XGetWindowAttributes(X_Dpy, win, &wattr)) if (!XGetWindowAttributes(X_Dpy, win, &wattr))
return(NULL); return NULL;
if (sc == NULL) { if (sc == NULL) {
if ((sc = screen_find(wattr.root)) == NULL) if ((sc = screen_find(wattr.root)) == NULL)
return(NULL); return NULL;
mapped = 1; mapped = 1;
} else { } else {
if (wattr.override_redirect || wattr.map_state != IsViewable) if (wattr.override_redirect || wattr.map_state != IsViewable)
return(NULL); return NULL;
mapped = wattr.map_state != IsUnmapped; mapped = wattr.map_state != IsUnmapped;
} }
@ -67,12 +67,15 @@ client_init(Window win, struct screen_ctx *sc, int active)
cc = xmalloc(sizeof(*cc)); cc = xmalloc(sizeof(*cc));
cc->sc = sc; cc->sc = sc;
cc->win = win; cc->win = win;
cc->name = NULL;
cc->label = NULL; cc->label = NULL;
cc->gc = NULL; cc->gc = NULL;
cc->res_class = NULL;
cc->res_name = NULL;
cc->flags = 0; cc->flags = 0;
cc->stackingorder = 0; cc->stackingorder = 0;
cc->initial_state = 0;
memset(&cc->hint, 0, sizeof(cc->hint)); memset(&cc->hint, 0, sizeof(cc->hint));
memset(&cc->ch, 0, sizeof(cc->ch));
TAILQ_INIT(&cc->nameq); TAILQ_INIT(&cc->nameq);
cc->geom.x = wattr.x; cc->geom.x = wattr.x;
@ -83,13 +86,13 @@ client_init(Window win, struct screen_ctx *sc, int active)
cc->obwidth = wattr.border_width; cc->obwidth = wattr.border_width;
cc->bwidth = Conf.bwidth; cc->bwidth = Conf.bwidth;
client_setname(cc); client_set_name(cc);
conf_client(cc); conf_client(cc);
XGetClassHint(X_Dpy, cc->win, &cc->ch);
client_wm_hints(cc); client_wm_hints(cc);
client_class_hint(cc);
client_wm_protocols(cc); client_wm_protocols(cc);
client_getsizehints(cc); client_get_sizehints(cc);
client_transient(cc); client_transient(cc);
client_mwm_hints(cc); client_mwm_hints(cc);
@ -101,10 +104,10 @@ client_init(Window win, struct screen_ctx *sc, int active)
cc->ptr.y = cc->geom.h / 2; cc->ptr.y = cc->geom.h / 2;
if (wattr.map_state != IsViewable) { if (wattr.map_state != IsViewable) {
client_placecalc(cc); client_placement(cc);
client_resize(cc, 0); client_resize(cc, 0);
if ((cc->wmh) && (cc->wmh->flags & StateHint)) if (cc->initial_state)
client_set_wm_state(cc, cc->wmh->initial_state); xu_set_wm_state(cc->win, cc->initial_state);
} else { } else {
if ((active == 0) && (XQueryPointer(X_Dpy, cc->win, &rwin, if ((active == 0) && (XQueryPointer(X_Dpy, cc->win, &rwin,
&cwin, &x, &y, &wx, &wy, &mask)) && (cwin != None)) &cwin, &x, &y, &wx, &wy, &mask)) && (cwin != None))
@ -125,7 +128,8 @@ client_init(Window win, struct screen_ctx *sc, int active)
xu_ewmh_net_client_list_stacking(sc); xu_ewmh_net_client_list_stacking(sc);
xu_ewmh_restore_net_wm_state(cc); xu_ewmh_restore_net_wm_state(cc);
if (client_get_wm_state(cc) == IconicState) xu_get_wm_state(cc->win, &state);
if (state == IconicState)
client_hide(cc); client_hide(cc);
else else
client_show(cc); client_show(cc);
@ -149,9 +153,31 @@ out:
XUngrabServer(X_Dpy); XUngrabServer(X_Dpy);
if (active) if (active)
client_setactive(cc); client_set_active(cc);
return(cc); return cc;
}
struct client_ctx *
client_current(struct screen_ctx *sc)
{
struct screen_ctx *_sc;
struct client_ctx *cc;
if (sc) {
TAILQ_FOREACH(cc, &sc->clientq, entry) {
if (cc->flags & CLIENT_ACTIVE)
return cc;
}
} else {
TAILQ_FOREACH(_sc, &Screenq, entry) {
TAILQ_FOREACH(cc, &_sc->clientq, entry) {
if (cc->flags & CLIENT_ACTIVE)
return cc;
}
}
}
return NULL;
} }
struct client_ctx * struct client_ctx *
@ -163,10 +189,30 @@ client_find(Window win)
TAILQ_FOREACH(sc, &Screenq, entry) { TAILQ_FOREACH(sc, &Screenq, entry) {
TAILQ_FOREACH(cc, &sc->clientq, entry) { TAILQ_FOREACH(cc, &sc->clientq, entry) {
if (cc->win == win) if (cc->win == win)
return(cc); return cc;
} }
} }
return(NULL); return NULL;
}
struct client_ctx *
client_next(struct client_ctx *cc)
{
struct screen_ctx *sc = cc->sc;
struct client_ctx *newcc;
return(((newcc = TAILQ_NEXT(cc, entry)) != NULL) ?
newcc : TAILQ_FIRST(&sc->clientq));
}
struct client_ctx *
client_prev(struct client_ctx *cc)
{
struct screen_ctx *sc = cc->sc;
struct client_ctx *newcc;
return(((newcc = TAILQ_PREV(cc, client_q, entry)) != NULL) ?
newcc : TAILQ_LAST(&sc->clientq, client_q));
} }
void void
@ -189,18 +235,15 @@ client_remove(struct client_ctx *cc)
free(wn); free(wn);
} }
if (cc->ch.res_class) free(cc->name);
XFree(cc->ch.res_class); free(cc->label);
if (cc->ch.res_name) free(cc->res_class);
XFree(cc->ch.res_name); free(cc->res_name);
if (cc->wmh)
XFree(cc->wmh);
free(cc); free(cc);
} }
void void
client_setactive(struct client_ctx *cc) client_set_active(struct client_ctx *cc)
{ {
struct screen_ctx *sc = cc->sc; struct screen_ctx *sc = cc->sc;
struct client_ctx *oldcc; struct client_ctx *oldcc;
@ -216,7 +259,7 @@ client_setactive(struct client_ctx *cc)
RevertToPointerRoot, CurrentTime); RevertToPointerRoot, CurrentTime);
} }
if (cc->flags & CLIENT_WM_TAKE_FOCUS) if (cc->flags & CLIENT_WM_TAKE_FOCUS)
client_msg(cc, cwmh[WM_TAKE_FOCUS], Last_Event_Time); xu_send_clientmsg(cc->win, cwmh[WM_TAKE_FOCUS], Last_Event_Time);
if ((oldcc = client_current(sc)) != NULL) { if ((oldcc = client_current(sc)) != NULL) {
oldcc->flags &= ~CLIENT_ACTIVE; oldcc->flags &= ~CLIENT_ACTIVE;
@ -234,28 +277,6 @@ client_setactive(struct client_ctx *cc)
xu_ewmh_net_active_window(sc, cc->win); xu_ewmh_net_active_window(sc, cc->win);
} }
struct client_ctx *
client_current(struct screen_ctx *sc)
{
struct screen_ctx *_sc;
struct client_ctx *cc;
if (sc) {
TAILQ_FOREACH(cc, &sc->clientq, entry) {
if (cc->flags & CLIENT_ACTIVE)
return(cc);
}
} else {
TAILQ_FOREACH(_sc, &Screenq, entry) {
TAILQ_FOREACH(cc, &_sc->clientq, entry) {
if (cc->flags & CLIENT_ACTIVE)
return(cc);
}
}
}
return(NULL);
}
void void
client_toggle_freeze(struct client_ctx *cc) client_toggle_freeze(struct client_ctx *cc)
{ {
@ -316,7 +337,7 @@ client_toggle_fullscreen(struct client_ctx *cc)
area = screen_area(sc, area = screen_area(sc,
cc->geom.x + cc->geom.w / 2, cc->geom.x + cc->geom.w / 2,
cc->geom.y + cc->geom.h / 2, CWM_NOGAP); cc->geom.y + cc->geom.h / 2, 0);
cc->bwidth = 0; cc->bwidth = 0;
cc->geom = area; cc->geom = area;
@ -354,7 +375,7 @@ client_toggle_maximize(struct client_ctx *cc)
area = screen_area(sc, area = screen_area(sc,
cc->geom.x + cc->geom.w / 2, cc->geom.x + cc->geom.w / 2,
cc->geom.y + cc->geom.h / 2, CWM_GAP); cc->geom.y + cc->geom.h / 2, 1);
cc->geom.x = area.x; cc->geom.x = area.x;
cc->geom.y = area.y; cc->geom.y = area.y;
@ -388,7 +409,7 @@ client_toggle_vmaximize(struct client_ctx *cc)
area = screen_area(sc, area = screen_area(sc,
cc->geom.x + cc->geom.w / 2, cc->geom.x + cc->geom.w / 2,
cc->geom.y + cc->geom.h / 2, CWM_GAP); cc->geom.y + cc->geom.h / 2, 1);
cc->geom.y = area.y; cc->geom.y = area.y;
cc->geom.h = area.h - (cc->bwidth * 2); cc->geom.h = area.h - (cc->bwidth * 2);
@ -420,7 +441,7 @@ client_toggle_hmaximize(struct client_ctx *cc)
area = screen_area(sc, area = screen_area(sc,
cc->geom.x + cc->geom.w / 2, cc->geom.x + cc->geom.w / 2,
cc->geom.y + cc->geom.h / 2, CWM_GAP); cc->geom.y + cc->geom.h / 2, 1);
cc->geom.x = area.x; cc->geom.x = area.x;
cc->geom.w = area.w - (cc->bwidth * 2); cc->geom.w = area.w - (cc->bwidth * 2);
@ -491,7 +512,7 @@ void
client_ptr_inbound(struct client_ctx *cc, int getpos) client_ptr_inbound(struct client_ctx *cc, int getpos)
{ {
if (getpos) if (getpos)
xu_ptr_getpos(cc->win, &cc->ptr.x, &cc->ptr.y); xu_ptr_get(cc->win, &cc->ptr.x, &cc->ptr.y);
if (cc->ptr.x < 0) if (cc->ptr.x < 0)
cc->ptr.x = 0; cc->ptr.x = 0;
@ -502,21 +523,21 @@ client_ptr_inbound(struct client_ctx *cc, int getpos)
else if (cc->ptr.y > cc->geom.h - 1) else if (cc->ptr.y > cc->geom.h - 1)
cc->ptr.y = cc->geom.h - 1; cc->ptr.y = cc->geom.h - 1;
client_ptrwarp(cc); client_ptr_warp(cc);
} }
void void
client_ptrwarp(struct client_ctx *cc) client_ptr_warp(struct client_ctx *cc)
{ {
xu_ptr_setpos(cc->win, cc->ptr.x, cc->ptr.y); xu_ptr_set(cc->win, cc->ptr.x, cc->ptr.y);
} }
void void
client_ptrsave(struct client_ctx *cc) client_ptr_save(struct client_ctx *cc)
{ {
int x, y; int x, y;
xu_ptr_getpos(cc->win, &x, &y); xu_ptr_get(cc->win, &x, &y);
if (client_inbound(cc, x, y)) { if (client_inbound(cc, x, y)) {
cc->ptr.x = x; cc->ptr.x = x;
cc->ptr.y = y; cc->ptr.y = y;
@ -536,7 +557,7 @@ client_hide(struct client_ctx *cc)
xu_ewmh_net_active_window(cc->sc, None); xu_ewmh_net_active_window(cc->sc, None);
} }
cc->flags |= CLIENT_HIDDEN; cc->flags |= CLIENT_HIDDEN;
client_set_wm_state(cc, IconicState); xu_set_wm_state(cc->win, IconicState);
} }
void void
@ -545,7 +566,7 @@ client_show(struct client_ctx *cc)
XMapRaised(X_Dpy, cc->win); XMapRaised(X_Dpy, cc->win);
cc->flags &= ~CLIENT_HIDDEN; cc->flags &= ~CLIENT_HIDDEN;
client_set_wm_state(cc, NormalState); xu_set_wm_state(cc->win, NormalState);
client_draw_border(cc); client_draw_border(cc);
} }
@ -584,6 +605,23 @@ client_draw_border(struct client_ctx *cc)
XSetWindowBorder(X_Dpy, cc->win, pixel); XSetWindowBorder(X_Dpy, cc->win, pixel);
} }
static void
client_class_hint(struct client_ctx *cc)
{
XClassHint ch;
if (XGetClassHint(X_Dpy, cc->win, &ch)) {
if (ch.res_class) {
cc->res_class = xstrdup(ch.res_class);
XFree(ch.res_class);
}
if (ch.res_name) {
cc->res_name = xstrdup(ch.res_name);
XFree(ch.res_name);
}
}
}
static void static void
client_wm_protocols(struct client_ctx *cc) client_wm_protocols(struct client_ctx *cc)
{ {
@ -604,149 +642,60 @@ client_wm_protocols(struct client_ctx *cc)
void void
client_wm_hints(struct client_ctx *cc) client_wm_hints(struct client_ctx *cc)
{ {
if ((cc->wmh = XGetWMHints(X_Dpy, cc->win)) == NULL) XWMHints *wmh;
return;
if ((wmh = XGetWMHints(X_Dpy, cc->win)) != NULL) {
if ((cc->wmh->flags & InputHint) && (cc->wmh->input)) if ((wmh->flags & InputHint) && (wmh->input))
cc->flags |= CLIENT_INPUT; cc->flags |= CLIENT_INPUT;
if ((wmh->flags & XUrgencyHint))
if ((cc->wmh->flags & XUrgencyHint)) client_urgency(cc);
client_urgency(cc); if ((wmh->flags & StateHint))
} cc->initial_state = wmh->initial_state;
XFree(wmh);
void }
client_msg(struct client_ctx *cc, Atom proto, Time ts)
{
XClientMessageEvent cm;
(void)memset(&cm, 0, sizeof(cm));
cm.type = ClientMessage;
cm.window = cc->win;
cm.message_type = cwmh[WM_PROTOCOLS];
cm.format = 32;
cm.data.l[0] = proto;
cm.data.l[1] = ts;
XSendEvent(X_Dpy, cc->win, False, NoEventMask, (XEvent *)&cm);
} }
void void
client_close(struct client_ctx *cc) client_close(struct client_ctx *cc)
{ {
if (cc->flags & CLIENT_WM_DELETE_WINDOW) if (cc->flags & CLIENT_WM_DELETE_WINDOW)
client_msg(cc, cwmh[WM_DELETE_WINDOW], CurrentTime); xu_send_clientmsg(cc->win, cwmh[WM_DELETE_WINDOW], CurrentTime);
else else
XKillClient(X_Dpy, cc->win); XKillClient(X_Dpy, cc->win);
} }
void void
client_setname(struct client_ctx *cc) client_set_name(struct client_ctx *cc)
{ {
struct winname *wn; struct winname *wn;
char *newname; char *newname;
int i = 0; int i = 0;
if (!xu_getstrprop(cc->win, ewmh[_NET_WM_NAME], &newname)) if (!xu_get_strprop(cc->win, ewmh[_NET_WM_NAME], &newname))
if (!xu_getstrprop(cc->win, XA_WM_NAME, &newname)) if (!xu_get_strprop(cc->win, XA_WM_NAME, &newname))
newname = xstrdup(""); newname = xstrdup("");
TAILQ_FOREACH(wn, &cc->nameq, entry) { TAILQ_FOREACH(wn, &cc->nameq, entry) {
if (strcmp(wn->name, newname) == 0) { if (strcmp(wn->name, newname) == 0)
/* Move to the last since we got a hit. */
TAILQ_REMOVE(&cc->nameq, wn, entry); TAILQ_REMOVE(&cc->nameq, wn, entry);
TAILQ_INSERT_TAIL(&cc->nameq, wn, entry);
goto match;
}
}
wn = xmalloc(sizeof(*wn));
wn->name = newname;
TAILQ_INSERT_TAIL(&cc->nameq, wn, entry);
match:
cc->name = wn->name;
/* Do some garbage collection. */
TAILQ_FOREACH(wn, &cc->nameq, entry)
i++; i++;
if (i > Conf.nameqlen) { }
cc->name = newname;
wn = xmalloc(sizeof(*wn));
wn->name = xstrdup(newname);
TAILQ_INSERT_TAIL(&cc->nameq, wn, entry);
/* Garbage collection. */
if ((i + 1) > Conf.nameqlen) {
wn = TAILQ_FIRST(&cc->nameq); wn = TAILQ_FIRST(&cc->nameq);
TAILQ_REMOVE(&cc->nameq, wn, entry); TAILQ_REMOVE(&cc->nameq, wn, entry);
free(wn->name); free(wn->name);
free(wn); free(wn);
i--;
} }
} }
void
client_cycle(struct screen_ctx *sc, int flags)
{
struct client_ctx *newcc, *oldcc, *prevcc;
int again = 1;
if (TAILQ_EMPTY(&sc->clientq))
return;
prevcc = TAILQ_FIRST(&sc->clientq);
oldcc = client_current(sc);
if (oldcc == NULL)
oldcc = (flags & CWM_CYCLE_REVERSE) ?
TAILQ_LAST(&sc->clientq, client_q) :
TAILQ_FIRST(&sc->clientq);
newcc = oldcc;
while (again) {
again = 0;
newcc = (flags & CWM_CYCLE_REVERSE) ? client_prev(newcc) :
client_next(newcc);
/* Only cycle visible and non-ignored windows. */
if ((newcc->flags & (CLIENT_SKIP_CYCLE)) ||
((flags & CWM_CYCLE_INGROUP) &&
(newcc->gc != oldcc->gc)))
again = 1;
/* Is oldcc the only non-hidden window? */
if (newcc == oldcc) {
if (again)
return; /* No windows visible. */
break;
}
}
/* Reset when cycling mod is released. XXX I hate this hack */
sc->cycling = 1;
client_ptrsave(oldcc);
client_raise(prevcc);
client_raise(newcc);
if (!client_inbound(newcc, newcc->ptr.x, newcc->ptr.y)) {
newcc->ptr.x = newcc->geom.w / 2;
newcc->ptr.y = newcc->geom.h / 2;
}
client_ptrwarp(newcc);
}
static struct client_ctx *
client_next(struct client_ctx *cc)
{
struct screen_ctx *sc = cc->sc;
struct client_ctx *newcc;
return(((newcc = TAILQ_NEXT(cc, entry)) != NULL) ?
newcc : TAILQ_FIRST(&sc->clientq));
}
static struct client_ctx *
client_prev(struct client_ctx *cc)
{
struct screen_ctx *sc = cc->sc;
struct client_ctx *newcc;
return(((newcc = TAILQ_PREV(cc, client_q, entry)) != NULL) ?
newcc : TAILQ_LAST(&sc->clientq, client_q));
}
static void static void
client_placecalc(struct client_ctx *cc) client_placement(struct client_ctx *cc)
{ {
struct screen_ctx *sc = cc->sc; struct screen_ctx *sc = cc->sc;
@ -769,8 +718,8 @@ client_placecalc(struct client_ctx *cc)
struct geom area; struct geom area;
int xmouse, ymouse, xslack, yslack; int xmouse, ymouse, xslack, yslack;
xu_ptr_getpos(sc->rootwin, &xmouse, &ymouse); xu_ptr_get(sc->rootwin, &xmouse, &ymouse);
area = screen_area(sc, xmouse, ymouse, CWM_GAP); area = screen_area(sc, xmouse, ymouse, 1);
xmouse = MAX(MAX(xmouse, area.x) - cc->geom.w / 2, area.x); xmouse = MAX(MAX(xmouse, area.x) - cc->geom.w / 2, area.x);
ymouse = MAX(MAX(ymouse, area.y) - cc->geom.h / 2, area.y); ymouse = MAX(MAX(ymouse, area.y) - cc->geom.h / 2, area.y);
@ -803,7 +752,7 @@ client_mtf(struct client_ctx *cc)
} }
void void
client_getsizehints(struct client_ctx *cc) client_get_sizehints(struct client_ctx *cc)
{ {
long tmp; long tmp;
XSizeHints size; XSizeHints size;
@ -851,7 +800,7 @@ client_getsizehints(struct client_ctx *cc)
} }
void void
client_applysizehints(struct client_ctx *cc) client_apply_sizehints(struct client_ctx *cc)
{ {
Bool baseismin; Bool baseismin;
@ -902,7 +851,7 @@ client_mwm_hints(struct client_ctx *cc)
{ {
struct mwm_hints *mwmh; struct mwm_hints *mwmh;
if (xu_getprop(cc->win, cwmh[_MOTIF_WM_HINTS], if (xu_get_prop(cc->win, cwmh[_MOTIF_WM_HINTS],
cwmh[_MOTIF_WM_HINTS], MWM_HINTS_ELEMENTS, cwmh[_MOTIF_WM_HINTS], MWM_HINTS_ELEMENTS,
(unsigned char **)&mwmh) == MWM_HINTS_ELEMENTS) { (unsigned char **)&mwmh) == MWM_HINTS_ELEMENTS) {
if (mwmh->flags & MWM_FLAGS_DECORATIONS && if (mwmh->flags & MWM_FLAGS_DECORATIONS &&
@ -952,15 +901,15 @@ client_snapcalc(int n0, int n1, int e0, int e1, int snapdist)
/* possible to snap in both directions */ /* possible to snap in both directions */
if (s0 != 0 && s1 != 0) if (s0 != 0 && s1 != 0)
if (abs(s0) < abs(s1)) if (abs(s0) < abs(s1))
return(s0); return s0;
else else
return(s1); return s1;
else if (s0 != 0) else if (s0 != 0)
return(s0); return s0;
else if (s1 != 0) else if (s1 != 0)
return(s1); return s1;
else else
return(0); return 0;
} }
void void
@ -974,7 +923,7 @@ client_htile(struct client_ctx *cc)
i = n = 0; i = n = 0;
area = screen_area(sc, area = screen_area(sc,
cc->geom.x + cc->geom.w / 2, cc->geom.x + cc->geom.w / 2,
cc->geom.y + cc->geom.h / 2, CWM_GAP); cc->geom.y + cc->geom.h / 2, 1);
TAILQ_FOREACH(ci, &sc->clientq, entry) { TAILQ_FOREACH(ci, &sc->clientq, entry) {
if (ci->gc != cc->gc) if (ci->gc != cc->gc)
@ -1001,7 +950,7 @@ client_htile(struct client_ctx *cc)
cc->geom.w = area.w - (cc->bwidth * 2); cc->geom.w = area.w - (cc->bwidth * 2);
cc->geom.h = (area.h - (cc->bwidth * 2)) / 2; cc->geom.h = (area.h - (cc->bwidth * 2)) / 2;
client_resize(cc, 1); client_resize(cc, 1);
client_ptrwarp(cc); client_ptr_warp(cc);
mh = cc->geom.h + (cc->bwidth * 2); mh = cc->geom.h + (cc->bwidth * 2);
x = area.x; x = area.x;
@ -1042,7 +991,7 @@ client_vtile(struct client_ctx *cc)
i = n = 0; i = n = 0;
area = screen_area(sc, area = screen_area(sc,
cc->geom.x + cc->geom.w / 2, cc->geom.x + cc->geom.w / 2,
cc->geom.y + cc->geom.h / 2, CWM_GAP); cc->geom.y + cc->geom.h / 2, 1);
TAILQ_FOREACH(ci, &sc->clientq, entry) { TAILQ_FOREACH(ci, &sc->clientq, entry) {
if (ci->gc != cc->gc) if (ci->gc != cc->gc)
@ -1069,7 +1018,7 @@ client_vtile(struct client_ctx *cc)
cc->geom.w = (area.w - (cc->bwidth * 2)) / 2; cc->geom.w = (area.w - (cc->bwidth * 2)) / 2;
cc->geom.h = area.h - (cc->bwidth * 2); cc->geom.h = area.h - (cc->bwidth * 2);
client_resize(cc, 1); client_resize(cc, 1);
client_ptrwarp(cc); client_ptr_warp(cc);
mw = cc->geom.w + (cc->bwidth * 2); mw = cc->geom.w + (cc->bwidth * 2);
y = area.y; y = area.y;
@ -1098,25 +1047,3 @@ client_vtile(struct client_ctx *cc)
client_resize(ci, 1); client_resize(ci, 1);
} }
} }
long
client_get_wm_state(struct client_ctx *cc)
{
long *p, state = -1;
if (xu_getprop(cc->win, cwmh[WM_STATE], cwmh[WM_STATE], 2L,
(unsigned char **)&p) > 0) {
state = *p;
XFree(p);
}
return(state);
}
void
client_set_wm_state(struct client_ctx *cc, long state)
{
long data[] = { state, None };
XChangeProperty(X_Dpy, cc->win, cwmh[WM_STATE], cwmh[WM_STATE], 32,
PropModeReplace, (unsigned char *)data, 2);
}

72
conf.c
View File

@ -32,7 +32,7 @@
#include "calmwm.h" #include "calmwm.h"
static const char *conf_bind_getmask(const char *, unsigned int *); static const char *conf_bind_mask(const char *, unsigned int *);
static void conf_unbind_key(struct conf *, struct bind_ctx *); static void conf_unbind_key(struct conf *, struct bind_ctx *);
static void conf_unbind_mouse(struct conf *, struct bind_ctx *); static void conf_unbind_mouse(struct conf *, struct bind_ctx *);
@ -517,7 +517,7 @@ conf_group(struct screen_ctx *sc)
} }
static const char * static const char *
conf_bind_getmask(const char *name, unsigned int *mask) conf_bind_mask(const char *name, unsigned int *mask)
{ {
char *dash; char *dash;
const char *ch; const char *ch;
@ -525,13 +525,13 @@ conf_bind_getmask(const char *name, unsigned int *mask)
*mask = 0; *mask = 0;
if ((dash = strchr(name, '-')) == NULL) if ((dash = strchr(name, '-')) == NULL)
return(name); return name;
for (i = 0; i < nitems(bind_mods); i++) { for (i = 0; i < nitems(bind_mods); i++) {
if ((ch = strchr(name, bind_mods[i].ch)) != NULL && ch < dash) if ((ch = strchr(name, bind_mods[i].ch)) != NULL && ch < dash)
*mask |= bind_mods[i].mask; *mask |= bind_mods[i].mask;
} }
/* Skip past modifiers. */ /* Skip past modifiers. */
return(dash + 1); return (dash + 1);
} }
int int
@ -544,20 +544,20 @@ conf_bind_key(struct conf *c, const char *bind, const char *cmd)
if ((strcmp(bind, "all") == 0) && (cmd == NULL)) { if ((strcmp(bind, "all") == 0) && (cmd == NULL)) {
conf_unbind_key(c, NULL); conf_unbind_key(c, NULL);
return(1); return 1;
} }
kb = xmalloc(sizeof(*kb)); kb = xmalloc(sizeof(*kb));
key = conf_bind_getmask(bind, &kb->modmask); key = conf_bind_mask(bind, &kb->modmask);
kb->press.keysym = XStringToKeysym(key); kb->press.keysym = XStringToKeysym(key);
if (kb->press.keysym == NoSymbol) { if (kb->press.keysym == NoSymbol) {
warnx("unknown symbol: %s", key); warnx("unknown symbol: %s", key);
free(kb); free(kb);
return(0); return 0;
} }
conf_unbind_key(c, kb); conf_unbind_key(c, kb);
if (cmd == NULL) { if (cmd == NULL) {
free(kb); free(kb);
return(1); return 1;
} }
cargs = xcalloc(1, sizeof(*cargs)); cargs = xcalloc(1, sizeof(*cargs));
for (i = 0; i < nitems(name_to_func); i++) { for (i = 0; i < nitems(name_to_func); i++) {
@ -575,7 +575,7 @@ conf_bind_key(struct conf *c, const char *bind, const char *cmd)
out: out:
kb->cargs = cargs; kb->cargs = cargs;
TAILQ_INSERT_TAIL(&c->keybindq, kb, entry); TAILQ_INSERT_TAIL(&c->keybindq, kb, entry);
return(1); return 1;
} }
static void static void
@ -605,20 +605,20 @@ conf_bind_mouse(struct conf *c, const char *bind, const char *cmd)
if ((strcmp(bind, "all") == 0) && (cmd == NULL)) { if ((strcmp(bind, "all") == 0) && (cmd == NULL)) {
conf_unbind_mouse(c, NULL); conf_unbind_mouse(c, NULL);
return(1); return 1;
} }
mb = xmalloc(sizeof(*mb)); mb = xmalloc(sizeof(*mb));
button = conf_bind_getmask(bind, &mb->modmask); button = conf_bind_mask(bind, &mb->modmask);
mb->press.button = strtonum(button, Button1, Button5, &errstr); mb->press.button = strtonum(button, Button1, Button5, &errstr);
if (errstr) { if (errstr) {
warnx("button number is %s: %s", errstr, button); warnx("button number is %s: %s", errstr, button);
free(mb); free(mb);
return(0); return 0;
} }
conf_unbind_mouse(c, mb); conf_unbind_mouse(c, mb);
if (cmd == NULL) { if (cmd == NULL) {
free(mb); free(mb);
return(1); return 1;
} }
cargs = xcalloc(1, sizeof(*cargs)); cargs = xcalloc(1, sizeof(*cargs));
for (i = 0; i < nitems(name_to_func); i++) { for (i = 0; i < nitems(name_to_func); i++) {
@ -636,7 +636,7 @@ conf_bind_mouse(struct conf *c, const char *bind, const char *cmd)
out: out:
mb->cargs = cargs; mb->cargs = cargs;
TAILQ_INSERT_TAIL(&c->mousebindq, mb, entry); TAILQ_INSERT_TAIL(&c->mousebindq, mb, entry);
return(1); return 1;
} }
static void static void
@ -696,47 +696,3 @@ conf_grab_mouse(Window win)
} }
} }
} }
static char *cwmhints[] = {
"WM_STATE",
"WM_DELETE_WINDOW",
"WM_TAKE_FOCUS",
"WM_PROTOCOLS",
"_MOTIF_WM_HINTS",
"UTF8_STRING",
"WM_CHANGE_STATE",
};
static char *ewmhints[] = {
"_NET_SUPPORTED",
"_NET_SUPPORTING_WM_CHECK",
"_NET_ACTIVE_WINDOW",
"_NET_CLIENT_LIST",
"_NET_CLIENT_LIST_STACKING",
"_NET_NUMBER_OF_DESKTOPS",
"_NET_CURRENT_DESKTOP",
"_NET_DESKTOP_VIEWPORT",
"_NET_DESKTOP_GEOMETRY",
"_NET_VIRTUAL_ROOTS",
"_NET_SHOWING_DESKTOP",
"_NET_DESKTOP_NAMES",
"_NET_WORKAREA",
"_NET_WM_NAME",
"_NET_WM_DESKTOP",
"_NET_CLOSE_WINDOW",
"_NET_WM_STATE",
"_NET_WM_STATE_STICKY",
"_NET_WM_STATE_MAXIMIZED_VERT",
"_NET_WM_STATE_MAXIMIZED_HORZ",
"_NET_WM_STATE_HIDDEN",
"_NET_WM_STATE_FULLSCREEN",
"_NET_WM_STATE_DEMANDS_ATTENTION",
"_NET_WM_STATE_SKIP_PAGER",
"_NET_WM_STATE_SKIP_TASKBAR",
"_CWM_WM_STATE_FREEZE",
};
void
conf_atoms(void)
{
XInternAtoms(X_Dpy, cwmhints, nitems(cwmhints), False, cwmh);
XInternAtoms(X_Dpy, ewmhints, nitems(ewmhints), False, ewmh);
}

46
group.c
View File

@ -35,7 +35,7 @@
static struct group_ctx *group_next(struct group_ctx *); static struct group_ctx *group_next(struct group_ctx *);
static struct group_ctx *group_prev(struct group_ctx *); static struct group_ctx *group_prev(struct group_ctx *);
static void group_restack(struct group_ctx *); static void group_restack(struct group_ctx *);
static void group_setactive(struct group_ctx *); static void group_set_active(struct group_ctx *);
void void
group_assign(struct group_ctx *gc, struct client_ctx *cc) group_assign(struct group_ctx *gc, struct client_ctx *cc)
@ -45,7 +45,7 @@ group_assign(struct group_ctx *gc, struct client_ctx *cc)
cc->gc = gc; cc->gc = gc;
xu_ewmh_net_wm_desktop(cc); xu_ewmh_set_net_wm_desktop(cc);
} }
void void
@ -79,7 +79,7 @@ group_show(struct group_ctx *gc)
client_show(cc); client_show(cc);
} }
group_restack(gc); group_restack(gc);
group_setactive(gc); group_set_active(gc);
} }
static void static void
@ -134,11 +134,11 @@ group_init(struct screen_ctx *sc, int num, const char *name)
TAILQ_INSERT_TAIL(&sc->groupq, gc, entry); TAILQ_INSERT_TAIL(&sc->groupq, gc, entry);
if (num == 1) if (num == 1)
group_setactive(gc); group_set_active(gc);
} }
void void
group_setactive(struct group_ctx *gc) group_set_active(struct group_ctx *gc)
{ {
struct screen_ctx *sc = gc->sc; struct screen_ctx *sc = gc->sc;
@ -190,9 +190,9 @@ group_holds_only_sticky(struct group_ctx *gc)
if (cc->gc != gc) if (cc->gc != gc)
continue; continue;
if (!(cc->flags & CLIENT_STICKY)) if (!(cc->flags & CLIENT_STICKY))
return(0); return 0;
} }
return(1); return 1;
} }
int int
@ -205,9 +205,9 @@ group_holds_only_hidden(struct group_ctx *gc)
if (cc->gc != gc) if (cc->gc != gc)
continue; continue;
if (!(cc->flags & (CLIENT_HIDDEN | CLIENT_STICKY))) if (!(cc->flags & (CLIENT_HIDDEN | CLIENT_STICKY)))
return(0); return 0;
} }
return(1); return 1;
} }
void void
@ -297,7 +297,7 @@ group_cycle(struct screen_ctx *sc, int flags)
if (group_holds_only_hidden(showgroup)) if (group_holds_only_hidden(showgroup))
group_show(showgroup); group_show(showgroup);
else else
group_setactive(showgroup); group_set_active(showgroup);
} }
static struct group_ctx * static struct group_ctx *
@ -326,23 +326,21 @@ group_restore(struct client_ctx *cc)
struct screen_ctx *sc = cc->sc; struct screen_ctx *sc = cc->sc;
struct group_ctx *gc; struct group_ctx *gc;
int num; int num;
long *grpnum; long grpnum;
if (xu_getprop(cc->win, ewmh[_NET_WM_DESKTOP], XA_CARDINAL, 1L, if (!xu_ewmh_get_net_wm_desktop(cc, &grpnum))
(unsigned char **)&grpnum) <= 0) return 0;
return(0);
num = (*grpnum == -1) ? 0 : *grpnum; num = (grpnum == -1) ? 0 : grpnum;
num = MIN(num, (Conf.ngroups - 1)); num = MIN(num, (Conf.ngroups - 1));
XFree(grpnum);
TAILQ_FOREACH(gc, &sc->groupq, entry) { TAILQ_FOREACH(gc, &sc->groupq, entry) {
if (gc->num == num) { if (gc->num == num) {
group_assign(gc, cc); group_assign(gc, cc);
return(1); return 1;
} }
} }
return(0); return 0;
} }
int int
@ -353,13 +351,13 @@ group_autogroup(struct client_ctx *cc)
struct group_ctx *gc; struct group_ctx *gc;
int num = -1, both_match = 0; int num = -1, both_match = 0;
if (cc->ch.res_class == NULL || cc->ch.res_name == NULL) if (cc->res_class == NULL || cc->res_name == NULL)
return(0); return 0;
TAILQ_FOREACH(ag, &Conf.autogroupq, entry) { TAILQ_FOREACH(ag, &Conf.autogroupq, entry) {
if (strcmp(ag->class, cc->ch.res_class) == 0) { if (strcmp(ag->class, cc->res_class) == 0) {
if ((ag->name != NULL) && if ((ag->name != NULL) &&
(strcmp(ag->name, cc->ch.res_name) == 0)) { (strcmp(ag->name, cc->res_name) == 0)) {
num = ag->num; num = ag->num;
both_match = 1; both_match = 1;
} else if (ag->name == NULL && !both_match) } else if (ag->name == NULL && !both_match)
@ -370,8 +368,8 @@ group_autogroup(struct client_ctx *cc)
TAILQ_FOREACH(gc, &sc->groupq, entry) { TAILQ_FOREACH(gc, &sc->groupq, entry) {
if (gc->num == num) { if (gc->num == num) {
group_assign(gc, cc); group_assign(gc, cc);
return(1); return 1;
} }
} }
return(0); return 0;
} }

View File

@ -59,7 +59,7 @@ kbfunc_amount(int flags, int amt, int *mx, int *my)
if (flags & CWM_BIGAMOUNT) if (flags & CWM_BIGAMOUNT)
amt *= CWM_FACTOR; amt *= CWM_FACTOR;
switch (flags & DIRECTIONMASK) { switch (flags & (CWM_UP | CWM_DOWN | CWM_LEFT | CWM_RIGHT)) {
case CWM_UP: case CWM_UP:
*my -= amt; *my -= amt;
break; break;
@ -84,8 +84,8 @@ kbfunc_ptrmove(void *ctx, struct cargs *cargs)
kbfunc_amount(cargs->flag, Conf.mamount, &mx, &my); kbfunc_amount(cargs->flag, Conf.mamount, &mx, &my);
xu_ptr_getpos(sc->rootwin, &x, &y); xu_ptr_get(sc->rootwin, &x, &y);
xu_ptr_setpos(sc->rootwin, x + mx, y + my); xu_ptr_set(sc->rootwin, x + mx, y + my);
} }
void void
@ -132,7 +132,7 @@ kbfunc_client_move_kb(void *ctx, struct cargs *cargs)
area = screen_area(sc, area = screen_area(sc,
cc->geom.x + cc->geom.w / 2, cc->geom.x + cc->geom.w / 2,
cc->geom.y + cc->geom.h / 2, CWM_GAP); cc->geom.y + cc->geom.h / 2, 1);
cc->geom.x += client_snapcalc(cc->geom.x, cc->geom.x += client_snapcalc(cc->geom.x,
cc->geom.x + cc->geom.w + (cc->bwidth * 2), cc->geom.x + cc->geom.w + (cc->bwidth * 2),
area.x, area.x + area.w, sc->snapdist); area.x, area.x + area.w, sc->snapdist);
@ -183,7 +183,7 @@ kbfunc_client_move_mb(void *ctx, struct cargs *cargs)
area = screen_area(sc, area = screen_area(sc,
cc->geom.x + cc->geom.w / 2, cc->geom.x + cc->geom.w / 2,
cc->geom.y + cc->geom.h / 2, CWM_GAP); cc->geom.y + cc->geom.h / 2, 1);
cc->geom.x += client_snapcalc(cc->geom.x, cc->geom.x += client_snapcalc(cc->geom.x,
cc->geom.x + cc->geom.w + (cc->bwidth * 2), cc->geom.x + cc->geom.w + (cc->bwidth * 2),
area.x, area.x + area.w, sc->snapdist); area.x, area.x + area.w, sc->snapdist);
@ -247,9 +247,9 @@ kbfunc_client_resize_mb(void *ctx, struct cargs *cargs)
return; return;
client_raise(cc); client_raise(cc);
client_ptrsave(cc); client_ptr_save(cc);
xu_ptr_setpos(cc->win, cc->geom.w, cc->geom.h); xu_ptr_set(cc->win, cc->geom.w, cc->geom.h);
if (XGrabPointer(X_Dpy, cc->win, False, MOUSEMASK, if (XGrabPointer(X_Dpy, cc->win, False, MOUSEMASK,
GrabModeAsync, GrabModeAsync, None, Conf.cursor[CF_RESIZE], GrabModeAsync, GrabModeAsync, None, Conf.cursor[CF_RESIZE],
@ -269,7 +269,7 @@ kbfunc_client_resize_mb(void *ctx, struct cargs *cargs)
cc->geom.w = ev.xmotion.x; cc->geom.w = ev.xmotion.x;
cc->geom.h = ev.xmotion.y; cc->geom.h = ev.xmotion.y;
client_applysizehints(cc); client_apply_sizehints(cc);
client_resize(cc, 1); client_resize(cc, 1);
screen_prop_win_draw(sc, screen_prop_win_draw(sc,
"%4d x %-4d", cc->dim.w, cc->dim.h); "%4d x %-4d", cc->dim.w, cc->dim.h);
@ -298,7 +298,7 @@ kbfunc_client_snap(void *ctx, struct cargs *cargs)
area = screen_area(sc, area = screen_area(sc,
cc->geom.x + cc->geom.w / 2, cc->geom.x + cc->geom.w / 2,
cc->geom.y + cc->geom.h / 2, CWM_GAP); cc->geom.y + cc->geom.h / 2, 1);
flags = cargs->flag; flags = cargs->flag;
while (flags) { while (flags) {
@ -334,7 +334,7 @@ kbfunc_client_close(void *ctx, struct cargs *cargs)
void void
kbfunc_client_lower(void *ctx, struct cargs *cargs) kbfunc_client_lower(void *ctx, struct cargs *cargs)
{ {
client_ptrsave(ctx); client_ptr_save(ctx);
client_lower(ctx); client_lower(ctx);
} }
@ -402,13 +402,55 @@ void
kbfunc_client_cycle(void *ctx, struct cargs *cargs) kbfunc_client_cycle(void *ctx, struct cargs *cargs)
{ {
struct screen_ctx *sc = ctx; struct screen_ctx *sc = ctx;
struct client_ctx *newcc, *oldcc, *prevcc;
int again = 1, flags = cargs->flag;
/* For X apps that ignore/steal events. */ /* For X apps that ignore/steal events. */
if (cargs->xev == CWM_XEV_KEY) if (cargs->xev == CWM_XEV_KEY)
XGrabKeyboard(X_Dpy, sc->rootwin, True, XGrabKeyboard(X_Dpy, sc->rootwin, True,
GrabModeAsync, GrabModeAsync, CurrentTime); GrabModeAsync, GrabModeAsync, CurrentTime);
client_cycle(sc, cargs->flag); if (TAILQ_EMPTY(&sc->clientq))
return;
prevcc = TAILQ_FIRST(&sc->clientq);
oldcc = client_current(sc);
if (oldcc == NULL)
oldcc = (flags & CWM_CYCLE_REVERSE) ?
TAILQ_LAST(&sc->clientq, client_q) :
TAILQ_FIRST(&sc->clientq);
newcc = oldcc;
while (again) {
again = 0;
newcc = (flags & CWM_CYCLE_REVERSE) ? client_prev(newcc) :
client_next(newcc);
/* Only cycle visible and non-ignored windows. */
if ((newcc->flags & (CLIENT_SKIP_CYCLE)) ||
((flags & CWM_CYCLE_INGROUP) &&
(newcc->gc != oldcc->gc)))
again = 1;
/* Is oldcc the only non-hidden window? */
if (newcc == oldcc) {
if (again)
return; /* No windows visible. */
break;
}
}
/* Reset when cycling mod is released. XXX I hate this hack */
sc->cycling = 1;
client_ptr_save(oldcc);
client_raise(prevcc);
client_raise(newcc);
if (!client_inbound(newcc, newcc->ptr.x, newcc->ptr.y)) {
newcc->ptr.x = newcc->geom.w / 2;
newcc->ptr.y = newcc->geom.h / 2;
}
client_ptr_warp(newcc);
} }
void void
@ -489,8 +531,8 @@ kbfunc_menu_client(void *ctx, struct cargs *cargs)
cc = (struct client_ctx *)mi->ctx; cc = (struct client_ctx *)mi->ctx;
client_show(cc); client_show(cc);
if (old_cc) if (old_cc)
client_ptrsave(old_cc); client_ptr_save(old_cc);
client_ptrwarp(cc); client_ptr_warp(cc);
} }
menuq_clear(&menuq); menuq_clear(&menuq);

36
menu.c
View File

@ -94,7 +94,7 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, const char *prompt,
TAILQ_INIT(&resultq); TAILQ_INIT(&resultq);
xu_ptr_getpos(sc->rootwin, &xsave, &ysave); xu_ptr_get(sc->rootwin, &xsave, &ysave);
(void)memset(&mc, 0, sizeof(mc)); (void)memset(&mc, 0, sizeof(mc));
mc.sc = sc; mc.sc = sc;
@ -129,7 +129,7 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, const char *prompt,
CurrentTime) != GrabSuccess) { CurrentTime) != GrabSuccess) {
XftDrawDestroy(mc.xftdraw); XftDrawDestroy(mc.xftdraw);
XDestroyWindow(X_Dpy, mc.win); XDestroyWindow(X_Dpy, mc.win);
return(NULL); return NULL;
} }
XGetInputFocus(X_Dpy, &focuswin, &focusrevert); XGetInputFocus(X_Dpy, &focuswin, &focusrevert);
@ -178,14 +178,14 @@ out:
XSetInputFocus(X_Dpy, focuswin, focusrevert, CurrentTime); XSetInputFocus(X_Dpy, focuswin, focusrevert, CurrentTime);
/* restore if user didn't move */ /* restore if user didn't move */
xu_ptr_getpos(sc->rootwin, &xcur, &ycur); xu_ptr_get(sc->rootwin, &xcur, &ycur);
if (xcur == mc.geom.x && ycur == mc.geom.y) if (xcur == mc.geom.x && ycur == mc.geom.y)
xu_ptr_setpos(sc->rootwin, xsave, ysave); xu_ptr_set(sc->rootwin, xsave, ysave);
XUngrabPointer(X_Dpy, CurrentTime); XUngrabPointer(X_Dpy, CurrentTime);
XUngrabKeyboard(X_Dpy, CurrentTime); XUngrabKeyboard(X_Dpy, CurrentTime);
return(mi); return mi;
} }
static struct menu * static struct menu *
@ -213,7 +213,7 @@ menu_complete_path(struct menu_ctx *mc)
menuq_clear(&menuq); menuq_clear(&menuq);
return(mr); return mr;
} }
static struct menu * static struct menu *
@ -228,7 +228,7 @@ menu_handle_key(XEvent *e, struct menu_ctx *mc, struct menu_q *menuq,
wchar_t wc; wchar_t wc;
if (menu_keycode(&e->xkey, &ctl, chr) < 0) if (menu_keycode(&e->xkey, &ctl, chr) < 0)
return(NULL); return NULL;
switch (ctl) { switch (ctl) {
case CTL_ERASEONE: case CTL_ERASEONE:
@ -269,7 +269,7 @@ menu_handle_key(XEvent *e, struct menu_ctx *mc, struct menu_q *menuq,
mi->dummy = 1; mi->dummy = 1;
} }
mi->abort = 0; mi->abort = 0;
return(mi); return mi;
case CTL_WIPE: case CTL_WIPE:
mc->searchstr[0] = '\0'; mc->searchstr[0] = '\0';
mc->changed = 1; mc->changed = 1;
@ -284,7 +284,7 @@ menu_handle_key(XEvent *e, struct menu_ctx *mc, struct menu_q *menuq,
if ((mc->flags & CWM_MENU_FILE) && if ((mc->flags & CWM_MENU_FILE) &&
(strncmp(mc->searchstr, mi->text, (strncmp(mc->searchstr, mi->text,
strlen(mi->text))) == 0) strlen(mi->text))) == 0)
return(menu_complete_path(mc)); return menu_complete_path(mc);
/* /*
* Put common prefix of the results into searchstr * Put common prefix of the results into searchstr
@ -309,7 +309,7 @@ menu_handle_key(XEvent *e, struct menu_ctx *mc, struct menu_q *menuq,
mi->text[0] = '\0'; mi->text[0] = '\0';
mi->dummy = 1; mi->dummy = 1;
mi->abort = 1; mi->abort = 1;
return(mi); return mi;
default: default:
break; break;
} }
@ -327,7 +327,7 @@ menu_handle_key(XEvent *e, struct menu_ctx *mc, struct menu_q *menuq,
mc->listing = 0; mc->listing = 0;
} }
return(NULL); return NULL;
} }
static void static void
@ -368,7 +368,7 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq)
mc->num++; mc->num++;
} }
area = screen_area(sc, mc->geom.x, mc->geom.y, CWM_GAP); area = screen_area(sc, mc->geom.x, mc->geom.y, 1);
area.w += area.x - Conf.bwidth * 2; area.w += area.x - Conf.bwidth * 2;
area.h += area.y - Conf.bwidth * 2; area.h += area.y - Conf.bwidth * 2;
@ -390,7 +390,7 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq)
} }
if (mc->geom.x != xsave || mc->geom.y != ysave) if (mc->geom.x != xsave || mc->geom.y != ysave)
xu_ptr_setpos(sc->rootwin, mc->geom.x, mc->geom.y); xu_ptr_set(sc->rootwin, mc->geom.x, mc->geom.y);
XClearWindow(X_Dpy, mc->win); XClearWindow(X_Dpy, mc->win);
XMoveResizeWindow(X_Dpy, mc->win, mc->geom.x, mc->geom.y, XMoveResizeWindow(X_Dpy, mc->win, mc->geom.x, mc->geom.y,
@ -478,7 +478,7 @@ menu_handle_release(struct menu_ctx *mc, struct menu_q *resultq, int x, int y)
mi->text[0] = '\0'; mi->text[0] = '\0';
mi->dummy = 1; mi->dummy = 1;
} }
return(mi); return mi;
} }
static int static int
@ -498,7 +498,7 @@ menu_calc_entry(struct menu_ctx *mc, int x, int y)
if (entry == 0) if (entry == 0)
entry = -1; entry = -1;
return(entry); return entry;
} }
static int static int
@ -581,12 +581,12 @@ menu_keycode(XKeyEvent *ev, enum ctltype *ctl, char *chr)
} }
if (*ctl != CTL_NONE) if (*ctl != CTL_NONE)
return(0); return 0;
if (XLookupString(ev, chr, 32, &ks, NULL) < 0) if (XLookupString(ev, chr, 32, &ks, NULL) < 0)
return(-1); return -1;
return(0); return 0;
} }
void void

View File

@ -33,14 +33,14 @@
#include "calmwm.h" #include "calmwm.h"
static struct geom screen_apply_gap(struct screen_ctx *, struct geom); static struct geom screen_apply_gap(struct screen_ctx *, struct geom);
static void screen_scan(struct screen_ctx *, Window);
void void
screen_init(int which) screen_init(int which)
{ {
struct screen_ctx *sc; struct screen_ctx *sc;
Window *wins, w0, w1, active = None; Window active = None;
XSetWindowAttributes rootattr; XSetWindowAttributes rootattr;
unsigned int nwins, w;
sc = xmalloc(sizeof(*sc)); sc = xmalloc(sizeof(*sc));
@ -77,13 +77,7 @@ screen_init(int which)
XChangeWindowAttributes(X_Dpy, sc->rootwin, XChangeWindowAttributes(X_Dpy, sc->rootwin,
(CWEventMask | CWCursor), &rootattr); (CWEventMask | CWCursor), &rootattr);
/* Deal with existing clients. */ screen_scan(sc, active);
if (XQueryTree(X_Dpy, sc->rootwin, &w0, &w1, &wins, &nwins)) {
for (w = 0; w < nwins; w++)
(void)client_init(wins[w], sc, (active == wins[w]));
XFree(wins);
}
screen_updatestackingorder(sc); screen_updatestackingorder(sc);
if (Conf.xrandr) if (Conf.xrandr)
@ -94,6 +88,20 @@ screen_init(int which)
XSync(X_Dpy, False); XSync(X_Dpy, False);
} }
static void
screen_scan(struct screen_ctx *sc, Window active)
{
Window *wins, w0, w1;
unsigned int nwins, i;
if (XQueryTree(X_Dpy, sc->rootwin, &w0, &w1, &wins, &nwins)) {
for (i = 0; i < nwins; i++)
(void)client_init(wins[i], sc, (active == wins[i]));
XFree(wins);
}
}
struct screen_ctx * struct screen_ctx *
screen_find(Window win) screen_find(Window win)
{ {
@ -101,10 +109,10 @@ screen_find(Window win)
TAILQ_FOREACH(sc, &Screenq, entry) { TAILQ_FOREACH(sc, &Screenq, entry) {
if (sc->rootwin == win) if (sc->rootwin == win)
return(sc); return sc;
} }
warnx("%s: failure win 0x%lx", __func__, win); warnx("%s: failure win 0x%lx", __func__, win);
return(NULL); return NULL;
} }
void void
@ -138,11 +146,11 @@ region_find(struct screen_ctx *sc, int x, int y)
break; break;
} }
} }
return(rc); return rc;
} }
struct geom struct geom
screen_area(struct screen_ctx *sc, int x, int y, enum apply_gap apply_gap) screen_area(struct screen_ctx *sc, int x, int y, int apply_gap)
{ {
struct region_ctx *rc; struct region_ctx *rc;
struct geom area = sc->view; struct geom area = sc->view;
@ -156,7 +164,7 @@ screen_area(struct screen_ctx *sc, int x, int y, enum apply_gap apply_gap)
} }
if (apply_gap) if (apply_gap)
area = screen_apply_gap(sc, area); area = screen_apply_gap(sc, area);
return(area); return area;
} }
void void
@ -226,7 +234,7 @@ screen_apply_gap(struct screen_ctx *sc, struct geom geom)
geom.w -= (sc->gap.left + sc->gap.right); geom.w -= (sc->gap.left + sc->gap.right);
geom.h -= (sc->gap.top + sc->gap.bottom); geom.h -= (sc->gap.top + sc->gap.bottom);
return(geom); return geom;
} }
/* Bring back clients which are beyond the screen. */ /* Bring back clients which are beyond the screen. */

View File

@ -46,13 +46,13 @@ match_substr(char *sub, char *str, int zeroidx)
unsigned int n, flen; unsigned int n, flen;
if (sub == NULL || str == NULL) if (sub == NULL || str == NULL)
return(0); return 0;
len = strlen(str); len = strlen(str);
sublen = strlen(sub); sublen = strlen(sub);
if (sublen > len) if (sublen > len)
return(0); return 0;
if (zeroidx) if (zeroidx)
flen = 0; flen = 0;
@ -61,9 +61,9 @@ match_substr(char *sub, char *str, int zeroidx)
for (n = 0; n <= flen; n++) for (n = 0; n <= flen; n++)
if (strncasecmp(sub, str + n, sublen) == 0) if (strncasecmp(sub, str + n, sublen) == 0)
return(1); return 1;
return(0); return 0;
} }
void void
@ -94,7 +94,7 @@ search_match_client(struct menu_q *menuq, struct menu_q *resultq, char *search)
} }
/* Match on window resource class. */ /* Match on window resource class. */
if ((tier < 0) && match_substr(search, cc->ch.res_class, 0)) if ((tier < 0) && match_substr(search, cc->res_class, 0))
tier = 2; tier = 2;
if (tier < 0) if (tier < 0)

6
util.c
View File

@ -92,12 +92,12 @@ u_argv(char * const *argv)
char *p; char *p;
if (argv == 0) if (argv == 0)
return(NULL); return NULL;
for (i = 0; argv[i]; i++) for (i = 0; argv[i]; i++)
siz += strlen(argv[i]) + 1; siz += strlen(argv[i]) + 1;
if (siz == 0) if (siz == 0)
return(NULL); return NULL;
p = xmalloc(siz); p = xmalloc(siz);
strlcpy(p, argv[0], siz); strlcpy(p, argv[0], siz);
@ -105,7 +105,7 @@ u_argv(char * const *argv)
strlcat(p, " ", siz); strlcat(p, " ", siz);
strlcat(p, argv[i], siz); strlcat(p, argv[i], siz);
} }
return(p); return p;
} }
static void static void

View File

@ -84,13 +84,13 @@ xev_handle_maprequest(XEvent *ee)
return; return;
if ((old_cc = client_current(sc)) != NULL) if ((old_cc = client_current(sc)) != NULL)
client_ptrsave(old_cc); client_ptr_save(old_cc);
if ((cc = client_find(e->window)) == NULL) if ((cc = client_find(e->window)) == NULL)
cc = client_init(e->window, NULL, 0); cc = client_init(e->window, NULL, 0);
if ((cc != NULL) && (!(cc->flags & CLIENT_IGNORE))) if ((cc != NULL) && (!(cc->flags & CLIENT_IGNORE)))
client_ptrwarp(cc); client_ptr_warp(cc);
} }
static void static void
@ -103,7 +103,7 @@ xev_handle_unmapnotify(XEvent *ee)
if ((cc = client_find(e->window)) != NULL) { if ((cc = client_find(e->window)) != NULL) {
if (e->send_event) { if (e->send_event) {
client_set_wm_state(cc, WithdrawnState); xu_set_wm_state(cc->win, WithdrawnState);
} else { } else {
if (!(cc->flags & CLIENT_HIDDEN)) if (!(cc->flags & CLIENT_HIDDEN))
client_remove(cc); client_remove(cc);
@ -191,10 +191,10 @@ xev_handle_propertynotify(XEvent *ee)
if ((cc = client_find(e->window)) != NULL) { if ((cc = client_find(e->window)) != NULL) {
switch (e->atom) { switch (e->atom) {
case XA_WM_NORMAL_HINTS: case XA_WM_NORMAL_HINTS:
client_getsizehints(cc); client_get_sizehints(cc);
break; break;
case XA_WM_NAME: case XA_WM_NAME:
client_setname(cc); client_set_name(cc);
break; break;
case XA_WM_HINTS: case XA_WM_HINTS:
client_wm_hints(cc); client_wm_hints(cc);
@ -208,7 +208,7 @@ xev_handle_propertynotify(XEvent *ee)
break; break;
default: default:
if (e->atom == ewmh[_NET_WM_NAME]) if (e->atom == ewmh[_NET_WM_NAME])
client_setname(cc); client_set_name(cc);
break; break;
} }
} else { } else {
@ -230,7 +230,7 @@ xev_handle_enternotify(XEvent *ee)
Last_Event_Time = e->time; Last_Event_Time = e->time;
if ((cc = client_find(e->window)) != NULL) if ((cc = client_find(e->window)) != NULL)
client_setactive(cc); client_set_active(cc);
} }
static void static void
@ -399,9 +399,9 @@ xev_handle_clientmessage(XEvent *ee)
} else if (e->message_type == ewmh[_NET_ACTIVE_WINDOW]) { } else if (e->message_type == ewmh[_NET_ACTIVE_WINDOW]) {
if ((cc = client_find(e->window)) != NULL) { if ((cc = client_find(e->window)) != NULL) {
if ((old_cc = client_current(NULL)) != NULL) if ((old_cc = client_current(NULL)) != NULL)
client_ptrsave(old_cc); client_ptr_save(old_cc);
client_show(cc); client_show(cc);
client_ptrwarp(cc); client_ptr_warp(cc);
} }
} else if (e->message_type == ewmh[_NET_WM_DESKTOP]) { } else if (e->message_type == ewmh[_NET_WM_DESKTOP]) {
if ((cc = client_find(e->window)) != NULL) { if ((cc = client_find(e->window)) != NULL) {

View File

@ -43,7 +43,7 @@ xmalloc(size_t siz)
if ((p = malloc(siz)) == NULL) if ((p = malloc(siz)) == NULL)
err(1, "malloc"); err(1, "malloc");
return(p); return p;
} }
void * void *
@ -58,7 +58,7 @@ xcalloc(size_t no, size_t siz)
if ((p = calloc(no, siz)) == NULL) if ((p = calloc(no, siz)) == NULL)
err(1, "calloc"); err(1, "calloc");
return(p); return p;
} }
void * void *
@ -70,7 +70,7 @@ xreallocarray(void *ptr, size_t nmemb, size_t size)
if (p == NULL) if (p == NULL)
errx(1, "xreallocarray: out of memory (new_size %zu bytes)", errx(1, "xreallocarray: out of memory (new_size %zu bytes)",
nmemb * size); nmemb * size);
return(p); return p;
} }
char * char *
@ -81,7 +81,7 @@ xstrdup(const char *str)
if ((p = strdup(str)) == NULL) if ((p = strdup(str)) == NULL)
err(1, "strdup"); err(1, "strdup");
return(p); return p;
} }
int int
@ -94,7 +94,7 @@ xasprintf(char **ret, const char *fmt, ...)
i = xvasprintf(ret, fmt, ap); i = xvasprintf(ret, fmt, ap);
va_end(ap); va_end(ap);
return(i); return i;
} }
int int
@ -106,5 +106,5 @@ xvasprintf(char **ret, const char *fmt, va_list ap)
if (i == -1) if (i == -1)
err(1, "vasprintf"); err(1, "vasprintf");
return(i); return i;
} }

158
xutil.c
View File

@ -32,7 +32,7 @@
#include "calmwm.h" #include "calmwm.h"
void void
xu_ptr_getpos(Window win, int *x, int *y) xu_ptr_get(Window win, int *x, int *y)
{ {
Window w0, w1; Window w0, w1;
int tmp0, tmp1; int tmp0, tmp1;
@ -42,13 +42,13 @@ xu_ptr_getpos(Window win, int *x, int *y)
} }
void void
xu_ptr_setpos(Window win, int x, int y) xu_ptr_set(Window win, int x, int y)
{ {
XWarpPointer(X_Dpy, None, win, 0, 0, 0, 0, x, y); XWarpPointer(X_Dpy, None, win, 0, 0, 0, 0, x, y);
} }
int int
xu_getprop(Window win, Atom atm, Atom type, long len, unsigned char **p) xu_get_prop(Window win, Atom atm, Atom type, long len, unsigned char **p)
{ {
Atom realtype; Atom realtype;
unsigned long n, extra; unsigned long n, extra;
@ -56,16 +56,16 @@ xu_getprop(Window win, Atom atm, Atom type, long len, unsigned char **p)
if (XGetWindowProperty(X_Dpy, win, atm, 0L, len, False, type, if (XGetWindowProperty(X_Dpy, win, atm, 0L, len, False, type,
&realtype, &format, &n, &extra, p) != Success || *p == NULL) &realtype, &format, &n, &extra, p) != Success || *p == NULL)
return(-1); return -1;
if (n == 0) if (n == 0)
XFree(*p); XFree(*p);
return(n); return n;
} }
int int
xu_getstrprop(Window win, Atom atm, char **text) { xu_get_strprop(Window win, Atom atm, char **text) {
XTextProperty prop; XTextProperty prop;
char **list; char **list;
int nitems = 0; int nitems = 0;
@ -74,7 +74,7 @@ xu_getstrprop(Window win, Atom atm, char **text) {
XGetTextProperty(X_Dpy, win, &prop, atm); XGetTextProperty(X_Dpy, win, &prop, atm);
if (!prop.nitems) if (!prop.nitems)
return(0); return 0;
if (Xutf8TextPropertyToTextList(X_Dpy, &prop, &list, if (Xutf8TextPropertyToTextList(X_Dpy, &prop, &list,
&nitems) == Success && nitems > 0 && *list) { &nitems) == Success && nitems > 0 && *list) {
@ -90,10 +90,101 @@ xu_getstrprop(Window win, Atom atm, char **text) {
} }
XFreeStringList(list); XFreeStringList(list);
} }
XFree(prop.value); XFree(prop.value);
return(nitems); return nitems;
}
void
xu_send_clientmsg(Window win, Atom proto, Time ts)
{
XClientMessageEvent cm;
(void)memset(&cm, 0, sizeof(cm));
cm.type = ClientMessage;
cm.window = win;
cm.message_type = cwmh[WM_PROTOCOLS];
cm.format = 32;
cm.data.l[0] = proto;
cm.data.l[1] = ts;
XSendEvent(X_Dpy, win, False, NoEventMask, (XEvent *)&cm);
}
void
xu_get_wm_state(Window win, long *state)
{
long *p;
*state = -1;
if (xu_get_prop(win, cwmh[WM_STATE], cwmh[WM_STATE], 2L,
(unsigned char **)&p) > 0) {
*state = *p;
XFree(p);
}
}
void
xu_set_wm_state(Window win, long state)
{
long data[] = { state, None };
XChangeProperty(X_Dpy, win, cwmh[WM_STATE], cwmh[WM_STATE], 32,
PropModeReplace, (unsigned char *)data, 2);
}
void
xu_xorcolor(XftColor a, XftColor b, XftColor *r)
{
r->pixel = a.pixel ^ b.pixel;
r->color.red = a.color.red ^ b.color.red;
r->color.green = a.color.green ^ b.color.green;
r->color.blue = a.color.blue ^ b.color.blue;
r->color.alpha = 0xffff;
}
void
xu_atom_init(void)
{
char *cwmhints[] = {
"WM_STATE",
"WM_DELETE_WINDOW",
"WM_TAKE_FOCUS",
"WM_PROTOCOLS",
"_MOTIF_WM_HINTS",
"UTF8_STRING",
"WM_CHANGE_STATE",
};
char *ewmhints[] = {
"_NET_SUPPORTED",
"_NET_SUPPORTING_WM_CHECK",
"_NET_ACTIVE_WINDOW",
"_NET_CLIENT_LIST",
"_NET_CLIENT_LIST_STACKING",
"_NET_NUMBER_OF_DESKTOPS",
"_NET_CURRENT_DESKTOP",
"_NET_DESKTOP_VIEWPORT",
"_NET_DESKTOP_GEOMETRY",
"_NET_VIRTUAL_ROOTS",
"_NET_SHOWING_DESKTOP",
"_NET_DESKTOP_NAMES",
"_NET_WORKAREA",
"_NET_WM_NAME",
"_NET_WM_DESKTOP",
"_NET_CLOSE_WINDOW",
"_NET_WM_STATE",
"_NET_WM_STATE_STICKY",
"_NET_WM_STATE_MAXIMIZED_VERT",
"_NET_WM_STATE_MAXIMIZED_HORZ",
"_NET_WM_STATE_HIDDEN",
"_NET_WM_STATE_FULLSCREEN",
"_NET_WM_STATE_DEMANDS_ATTENTION",
"_NET_WM_STATE_SKIP_PAGER",
"_NET_WM_STATE_SKIP_TASKBAR",
"_CWM_WM_STATE_FREEZE",
};
XInternAtoms(X_Dpy, cwmhints, nitems(cwmhints), False, cwmh);
XInternAtoms(X_Dpy, ewmhints, nitems(ewmhints), False, ewmh);
} }
/* Root Window Properties */ /* Root Window Properties */
@ -211,14 +302,14 @@ xu_ewmh_get_net_active_window(struct screen_ctx *sc)
long *p; long *p;
Window win; Window win;
if ((xu_getprop(sc->rootwin, ewmh[_NET_ACTIVE_WINDOW], if ((xu_get_prop(sc->rootwin, ewmh[_NET_ACTIVE_WINDOW],
XA_WINDOW, 32, (unsigned char **)&p)) <= 0) XA_WINDOW, 32, (unsigned char **)&p)) <= 0)
return(None); return None;
win = (Window)*p; win = (Window)*p;
XFree(p); XFree(p);
return(win); return win;
} }
void void
@ -270,7 +361,7 @@ xu_ewmh_net_desktop_names(struct screen_ctx *sc)
/* Let group names be overwritten if _NET_DESKTOP_NAMES is set. */ /* Let group names be overwritten if _NET_DESKTOP_NAMES is set. */
if ((j = xu_getprop(sc->rootwin, ewmh[_NET_DESKTOP_NAMES], if ((j = xu_get_prop(sc->rootwin, ewmh[_NET_DESKTOP_NAMES],
cwmh[UTF8_STRING], 0xffffff, (unsigned char **)&prop_ret)) > 0) { cwmh[UTF8_STRING], 0xffffff, (unsigned char **)&prop_ret)) > 0) {
prop_ret[j - 1] = '\0'; /* paranoia */ prop_ret[j - 1] = '\0'; /* paranoia */
while (i < j) { while (i < j) {
@ -312,8 +403,21 @@ xu_ewmh_net_desktop_names(struct screen_ctx *sc)
} }
/* Application Window Properties */ /* Application Window Properties */
int
xu_ewmh_get_net_wm_desktop(struct client_ctx *cc, long *n)
{
long *p;
if (xu_get_prop(cc->win, ewmh[_NET_WM_DESKTOP], XA_CARDINAL, 1L,
(unsigned char **)&p) <= 0)
return 0;
*n = *p;
XFree(p);
return 1;
}
void void
xu_ewmh_net_wm_desktop(struct client_ctx *cc) xu_ewmh_set_net_wm_desktop(struct client_ctx *cc)
{ {
long num = 0xffffffff; long num = 0xffffffff;
@ -329,15 +433,15 @@ xu_ewmh_get_net_wm_state(struct client_ctx *cc, int *n)
{ {
Atom *state, *p = NULL; Atom *state, *p = NULL;
if ((*n = xu_getprop(cc->win, ewmh[_NET_WM_STATE], XA_ATOM, 64L, if ((*n = xu_get_prop(cc->win, ewmh[_NET_WM_STATE], XA_ATOM, 64L,
(unsigned char **)&p)) <= 0) (unsigned char **)&p)) <= 0)
return(NULL); return NULL;
state = xreallocarray(NULL, *n, sizeof(Atom)); state = xreallocarray(NULL, *n, sizeof(Atom));
(void)memcpy(state, p, *n * sizeof(Atom)); (void)memcpy(state, p, *n * sizeof(Atom));
XFree((char *)p); XFree((char *)p);
return(state); return state;
} }
void void
@ -345,9 +449,9 @@ xu_ewmh_handle_net_wm_state_msg(struct client_ctx *cc, int action,
Atom first, Atom second) Atom first, Atom second)
{ {
unsigned int i; unsigned int i;
static struct handlers { struct handlers {
int atom; Atom atom;
int property; int flag;
void (*toggle)(struct client_ctx *); void (*toggle)(struct client_ctx *);
} handlers[] = { } handlers[] = {
{ _NET_WM_STATE_STICKY, { _NET_WM_STATE_STICKY,
@ -385,11 +489,11 @@ xu_ewmh_handle_net_wm_state_msg(struct client_ctx *cc, int action,
continue; continue;
switch (action) { switch (action) {
case _NET_WM_STATE_ADD: case _NET_WM_STATE_ADD:
if (!(cc->flags & handlers[i].property)) if (!(cc->flags & handlers[i].flag))
handlers[i].toggle(cc); handlers[i].toggle(cc);
break; break;
case _NET_WM_STATE_REMOVE: case _NET_WM_STATE_REMOVE:
if (cc->flags & handlers[i].property) if (cc->flags & handlers[i].flag)
handlers[i].toggle(cc); handlers[i].toggle(cc);
break; break;
case _NET_WM_STATE_TOGGLE: case _NET_WM_STATE_TOGGLE:
@ -476,13 +580,3 @@ xu_ewmh_set_net_wm_state(struct client_ctx *cc)
XDeleteProperty(X_Dpy, cc->win, ewmh[_NET_WM_STATE]); XDeleteProperty(X_Dpy, cc->win, ewmh[_NET_WM_STATE]);
free(atoms); free(atoms);
} }
void
xu_xorcolor(XftColor a, XftColor b, XftColor *r)
{
r->pixel = a.pixel ^ b.pixel;
r->color.red = a.color.red ^ b.color.red;
r->color.green = a.color.green ^ b.color.green;
r->color.blue = a.color.blue ^ b.color.blue;
r->color.alpha = 0xffff;
}