mirror of
https://github.com/leahneukirchen/cwm.git
synced 2023-08-10 21:13:12 +03:00
Compare commits
No commits in common. "linux" and "v6.6" have entirely different histories.
17
Makefile
17
Makefile
@ -11,25 +11,26 @@ SRCS= calmwm.c screen.c xmalloc.c client.c menu.c \
|
||||
|
||||
OBJS= calmwm.o screen.o xmalloc.o client.o menu.o \
|
||||
search.o util.o xutil.o conf.o xevents.o group.o \
|
||||
kbfunc.o strlcpy.o strlcat.o parse.o \
|
||||
kbfunc.o strlcpy.o strlcat.o y.tab.o \
|
||||
strtonum.o reallocarray.o
|
||||
|
||||
PKG_CONFIG?= pkg-config
|
||||
|
||||
CPPFLAGS+= `${PKG_CONFIG} --cflags x11 xft xrandr`
|
||||
CPPFLAGS+= `pkg-config --cflags x11 xft xrandr`
|
||||
|
||||
CFLAGS?= -Wall -O2 -g -D_GNU_SOURCE
|
||||
|
||||
LDFLAGS+= `${PKG_CONFIG} --libs x11 xft xrandr`
|
||||
LDFLAGS+= `pkg-config --libs x11 xft xrandr`
|
||||
|
||||
MANPREFIX?= ${PREFIX}/share/man
|
||||
|
||||
all: ${PROG}
|
||||
|
||||
clean:
|
||||
rm -f ${OBJS} ${PROG} parse.c
|
||||
rm -f ${OBJS} ${PROG} y.tab.c
|
||||
|
||||
${PROG}: ${OBJS}
|
||||
y.tab.c: parse.y
|
||||
yacc parse.y
|
||||
|
||||
${PROG}: ${OBJS} y.tab.o
|
||||
${CC} ${OBJS} ${LDFLAGS} -o ${PROG}
|
||||
|
||||
.c.o:
|
||||
@ -50,5 +51,3 @@ sign:
|
||||
gpg2 --armor --detach-sign cwm-$$VERSION.tar.gz && \
|
||||
signify -S -s ~/.signify/cwm.sec -m cwm-$$VERSION.tar.gz && \
|
||||
sed -i '1cuntrusted comment: verify with cwm.pub' cwm-$$VERSION.tar.gz.sig
|
||||
|
||||
.PRECIOUS: parse.c
|
||||
|
22
README
22
README
@ -15,8 +15,7 @@ Releases are roughly coordinated.
|
||||
The revision controlled version is at https://github.com/leahneukirchen/cwm
|
||||
Releases can be found at http://leahneukirchen.org/releases
|
||||
|
||||
You are welcome to join the IRC channel ##cwm on irc.libera.chat
|
||||
to talk about cwm.
|
||||
You are welcome to join the IRC channel ##cwm on Freenode to talk about cwm.
|
||||
|
||||
|
||||
ChangeLog:
|
||||
@ -122,25 +121,6 @@ Changes made between OpenBSD 6.4 and 6.5
|
||||
* Introduced 'group-close-[n]' action to cwm(1) to close all windows
|
||||
within a specified group.
|
||||
|
||||
2020-05-22: Seventh public release 6.7 of portable cwm.
|
||||
|
||||
Changes made between OpenBSD 6.6 and 6.7
|
||||
* Allowed cwm(1) configuration of window size based on percentage of
|
||||
the master window during horizontal and vertical tiling actions.
|
||||
* Allowed use of window-htile and window-vtile with the "empty" group
|
||||
clients in cwm(1).
|
||||
|
||||
2022-04-30: Eighth public release 7.1 of portable cwm.
|
||||
|
||||
Changes made between OpenBSD 6.9 and 7.0
|
||||
* Changed cwm(1) maximization and full-screen mode toggling to keep
|
||||
the cursor within the window, preventing focus loss.
|
||||
|
||||
Changes made between OpenBSD 7.0 and 7.1
|
||||
* Added a cwm(1) "group-last" command that shows only the previously
|
||||
active group.
|
||||
* Allowed bare numbers for key and mouse bindings in cwm(1).
|
||||
|
||||
|
||||
--Leah Neukirchen <leah@vuxu.org>
|
||||
|
||||
|
20
calmwm.c
20
calmwm.c
@ -44,7 +44,6 @@ struct screen_q Screenq = TAILQ_HEAD_INITIALIZER(Screenq);
|
||||
struct conf Conf;
|
||||
volatile sig_atomic_t cwm_status;
|
||||
|
||||
void usage(void);
|
||||
static void sighdlr(int);
|
||||
static int x_errorhandler(Display *, XErrorEvent *);
|
||||
static int x_init(const char *);
|
||||
@ -89,10 +88,9 @@ main(int argc, char **argv)
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (signal(SIGCHLD, sighdlr) == SIG_ERR ||
|
||||
signal(SIGHUP, sighdlr) == SIG_ERR ||
|
||||
signal(SIGINT, sighdlr) == SIG_ERR ||
|
||||
signal(SIGTERM, sighdlr) == SIG_ERR)
|
||||
if (signal(SIGCHLD, sighdlr) == SIG_ERR)
|
||||
err(1, "signal");
|
||||
if (signal(SIGHUP, sighdlr) == SIG_ERR)
|
||||
err(1, "signal");
|
||||
|
||||
if (parse_config(Conf.conf_file, &Conf) == -1) {
|
||||
@ -128,7 +126,7 @@ main(int argc, char **argv)
|
||||
u_exec(fallback);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -146,7 +144,7 @@ x_init(const char *dpyname)
|
||||
|
||||
Conf.xrandr = XRRQueryExtension(X_Dpy, &Conf.xrandr_event_base, &i);
|
||||
|
||||
xu_atom_init();
|
||||
conf_atoms();
|
||||
conf_cursor(&Conf);
|
||||
|
||||
for (i = 0; i < ScreenCount(X_Dpy); i++)
|
||||
@ -184,7 +182,7 @@ static int
|
||||
x_wmerrorhandler(Display *dpy, XErrorEvent *e)
|
||||
{
|
||||
errx(1, "root window unavailable - perhaps another wm is running?");
|
||||
return 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -200,7 +198,7 @@ x_errorhandler(Display *dpy, XErrorEvent *e)
|
||||
|
||||
warnx("%s(0x%x): %s", req, (unsigned int)e->resourceid, msg);
|
||||
#endif
|
||||
return 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -219,10 +217,6 @@ sighdlr(int sig)
|
||||
case SIGHUP:
|
||||
cwm_status = CWM_EXEC_WM;
|
||||
break;
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
cwm_status = CWM_QUIT;
|
||||
break;
|
||||
}
|
||||
|
||||
errno = save_errno;
|
||||
|
129
calmwm.h
129
calmwm.h
@ -84,6 +84,7 @@ size_t strlcpy(char *, const char *, size_t);
|
||||
#define CWM_UP_LEFT (CWM_UP | CWM_LEFT)
|
||||
#define CWM_DOWN_RIGHT (CWM_DOWN | CWM_RIGHT)
|
||||
#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_REVERSE 0x0002
|
||||
@ -120,6 +121,11 @@ struct geom {
|
||||
int w;
|
||||
int h;
|
||||
};
|
||||
|
||||
enum apply_gap {
|
||||
CWM_NOGAP = 0,
|
||||
CWM_GAP
|
||||
};
|
||||
struct gap {
|
||||
int top;
|
||||
int bottom;
|
||||
@ -191,9 +197,8 @@ struct client_ctx {
|
||||
struct name_q nameq;
|
||||
char *name;
|
||||
char *label;
|
||||
char *res_class; /* class hint */
|
||||
char *res_name; /* class hint */
|
||||
int initial_state; /* wm hint */
|
||||
XClassHint ch;
|
||||
XWMHints *wmh;
|
||||
};
|
||||
TAILQ_HEAD(client_q, client_ctx);
|
||||
|
||||
@ -235,7 +240,6 @@ struct screen_ctx {
|
||||
struct region_q regionq;
|
||||
struct group_q groupq;
|
||||
struct group_ctx *group_active;
|
||||
struct group_ctx *group_last;
|
||||
Colormap colormap;
|
||||
Visual *visual;
|
||||
struct {
|
||||
@ -313,8 +317,6 @@ struct conf {
|
||||
int bwidth;
|
||||
int mamount;
|
||||
int snapdist;
|
||||
int htile;
|
||||
int vtile;
|
||||
struct gap gap;
|
||||
char *color[CWM_COLOR_NITEMS];
|
||||
char *font;
|
||||
@ -330,39 +332,30 @@ struct conf {
|
||||
|
||||
/* MWM hints */
|
||||
struct mwm_hints {
|
||||
#define MWM_HINTS_ELEMENTS 5L
|
||||
#define MWM_HINTS_ELEMENTS 3L
|
||||
#define MWM_FLAGS_STATUS (1<<3)
|
||||
|
||||
#define MWM_HINTS_FUNCTIONS (1L << 0)
|
||||
#define MWM_HINTS_DECORATIONS (1L << 1)
|
||||
#define MWM_HINTS_INPUT_MODE (1L << 2)
|
||||
#define MWM_HINTS_STATUS (1L << 3)
|
||||
#define MWM_FLAGS_FUNCTIONS (1<<0)
|
||||
#define MWM_FLAGS_DECORATIONS (1<<1)
|
||||
#define MWM_FLAGS_INPUT_MODE (1<<2)
|
||||
unsigned long flags;
|
||||
|
||||
#define MWM_FUNC_ALL (1L << 0)
|
||||
#define MWM_FUNC_RESIZE (1L << 1)
|
||||
#define MWM_FUNC_MOVE (1L << 2)
|
||||
#define MWM_FUNC_MINIMIZE (1L << 3)
|
||||
#define MWM_FUNC_MAXIMIZE (1L << 4)
|
||||
#define MWM_FUNC_CLOSE (1L << 5)
|
||||
#define MWM_FUNCS_ALL (1<<0)
|
||||
#define MWM_FUNCS_RESIZE (1<<1)
|
||||
#define MWM_FUNCS_MOVE (1<<2)
|
||||
#define MWM_FUNCS_MINIMIZE (1<<3)
|
||||
#define MWM_FUNCS_MAXIMIZE (1<<4)
|
||||
#define MWM_FUNCS_CLOSE (1<<5)
|
||||
unsigned long functions;
|
||||
|
||||
#define MWM_DECOR_ALL (1L << 0)
|
||||
#define MWM_DECOR_BORDER (1L << 1)
|
||||
#define MWM_DECOR_RESIZEH (1L << 2)
|
||||
#define MWM_DECOR_TITLE (1L << 3)
|
||||
#define MWM_DECOR_MENU (1L << 4)
|
||||
#define MWM_DECOR_MINIMIZE (1L << 5)
|
||||
#define MWM_DECOR_MAXIMIZE (1L << 6)
|
||||
#define MWM_DECOR_ALL (1<<0)
|
||||
#define MWM_DECOR_BORDER (1<<1)
|
||||
#define MWM_DECOR_RESIZE_HANDLE (1<<2)
|
||||
#define MWM_DECOR_TITLEBAR (1<<3)
|
||||
#define MWM_DECOR_MENU (1<<4)
|
||||
#define MWM_DECOR_MINIMIZE (1<<5)
|
||||
#define MWM_DECOR_MAXIMIZE (1<<6)
|
||||
unsigned long decorations;
|
||||
|
||||
#define MWM_INPUT_MODELESS 0
|
||||
#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
|
||||
#define MWM_INPUT_SYSTEM_MODAL 2
|
||||
#define MWM_INPUT_FULL_APPLICATION_MODAL 3
|
||||
long inputMode;
|
||||
|
||||
#define MWM_TEAROFF_WINDOW (1L << 0)
|
||||
unsigned long status;
|
||||
};
|
||||
|
||||
enum cwmh {
|
||||
@ -420,36 +413,38 @@ extern struct conf Conf;
|
||||
|
||||
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 *);
|
||||
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 *);
|
||||
struct client_ctx *client_find(Window);
|
||||
void client_get_sizehints(struct client_ctx *);
|
||||
long client_get_wm_state(struct client_ctx *);
|
||||
void client_getsizehints(struct client_ctx *);
|
||||
void client_hide(struct client_ctx *);
|
||||
void client_htile(struct client_ctx *);
|
||||
int client_inbound(struct client_ctx *, int, int);
|
||||
struct client_ctx *client_init(Window, struct screen_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 *);
|
||||
struct client_ctx *client_next(struct client_ctx *);
|
||||
struct client_ctx *client_prev(struct client_ctx *);
|
||||
int client_inbound(struct client_ctx *, int, int);
|
||||
struct client_ctx *client_init(Window, struct screen_ctx *, int);
|
||||
void client_ptr_inbound(struct client_ctx *, int);
|
||||
void client_ptr_save(struct client_ctx *);
|
||||
void client_ptr_warp(struct client_ctx *);
|
||||
void client_ptrsave(struct client_ctx *);
|
||||
void client_ptrwarp(struct client_ctx *);
|
||||
void client_raise(struct client_ctx *);
|
||||
void client_remove(struct client_ctx *);
|
||||
void client_resize(struct client_ctx *, int);
|
||||
void client_set_active(struct client_ctx *);
|
||||
void client_set_name(struct client_ctx *);
|
||||
void client_close(struct client_ctx *);
|
||||
void client_set_wm_state(struct client_ctx *, long);
|
||||
void client_setactive(struct client_ctx *);
|
||||
void client_setname(struct client_ctx *);
|
||||
void client_show(struct client_ctx *);
|
||||
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_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_skip_pager(struct client_ctx *);
|
||||
void client_toggle_skip_taskbar(struct client_ctx *);
|
||||
@ -479,16 +474,16 @@ void group_update_names(struct screen_ctx *);
|
||||
|
||||
void search_match_client(struct menu_q *, struct menu_q *,
|
||||
char *);
|
||||
void search_match_cmd(struct menu_q *, struct menu_q *,
|
||||
char *);
|
||||
void search_match_exec(struct menu_q *, struct menu_q *,
|
||||
char *);
|
||||
void search_match_group(struct menu_q *, struct menu_q *,
|
||||
char *);
|
||||
void search_match_path(struct menu_q *, struct menu_q *,
|
||||
char *);
|
||||
void search_match_text(struct menu_q *, struct menu_q *,
|
||||
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 *,
|
||||
char *);
|
||||
void search_print_client(struct menu *, int);
|
||||
@ -498,18 +493,19 @@ void search_print_text(struct menu *, int);
|
||||
void search_print_wm(struct menu *, int);
|
||||
|
||||
struct region_ctx *region_find(struct screen_ctx *, int, int);
|
||||
void screen_assert_clients_within(struct screen_ctx *);
|
||||
struct geom screen_area(struct screen_ctx *, int, 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_prop_win_create(struct screen_ctx *, Window);
|
||||
void screen_prop_win_destroy(struct screen_ctx *);
|
||||
void screen_prop_win_draw(struct screen_ctx *,
|
||||
const char *, ...)
|
||||
__attribute__((__format__ (printf, 2, 3)))
|
||||
__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_ptrmove(void *, struct cargs *);
|
||||
@ -534,7 +530,6 @@ void kbfunc_client_toggle_group(void *, struct cargs *);
|
||||
void kbfunc_client_movetogroup(void *, struct cargs *);
|
||||
void kbfunc_group_toggle(void *, struct cargs *);
|
||||
void kbfunc_group_only(void *, struct cargs *);
|
||||
void kbfunc_group_last(void *, struct cargs *);
|
||||
void kbfunc_group_close(void *, struct cargs *);
|
||||
void kbfunc_group_cycle(void *, struct cargs *);
|
||||
void kbfunc_group_toggle_all(void *, struct cargs *);
|
||||
@ -559,6 +554,7 @@ void menuq_clear(struct menu_q *);
|
||||
|
||||
int parse_config(const char *, struct conf *);
|
||||
|
||||
void conf_atoms(void);
|
||||
void conf_autogroup(struct conf *, int, const char *,
|
||||
const char *);
|
||||
int conf_bind_key(struct conf *, const char *,
|
||||
@ -581,16 +577,12 @@ void conf_group(struct screen_ctx *);
|
||||
|
||||
void xev_process(void);
|
||||
|
||||
int xu_get_prop(Window, Atom, Atom, long, unsigned char **);
|
||||
int xu_get_strprop(Window, Atom, char **);
|
||||
void xu_ptr_get(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);
|
||||
int xu_getprop(Window, Atom, Atom, long, unsigned char **);
|
||||
int xu_getstrprop(Window, Atom, char **);
|
||||
void xu_ptr_getpos(Window, int *, int *);
|
||||
void xu_ptr_setpos(Window, int, int);
|
||||
void xu_xorcolor(XftColor, XftColor, XftColor *);
|
||||
|
||||
void xu_atom_init(void);
|
||||
void xu_ewmh_net_supported(struct screen_ctx *);
|
||||
void xu_ewmh_net_supported_wm_check(struct screen_ctx *);
|
||||
void xu_ewmh_net_desktop_geometry(struct screen_ctx *);
|
||||
@ -599,16 +591,17 @@ void xu_ewmh_net_workarea(struct screen_ctx *);
|
||||
void xu_ewmh_net_client_list(struct screen_ctx *);
|
||||
void xu_ewmh_net_client_list_stacking(struct screen_ctx *);
|
||||
void xu_ewmh_net_active_window(struct screen_ctx *, Window);
|
||||
Window xu_ewmh_get_net_active_window(struct screen_ctx *);
|
||||
void xu_ewmh_net_number_of_desktops(struct screen_ctx *);
|
||||
void xu_ewmh_net_showing_desktop(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_desktop_names(struct screen_ctx *);
|
||||
int xu_ewmh_get_net_wm_desktop(struct client_ctx *, long *);
|
||||
void xu_ewmh_set_net_wm_desktop(struct client_ctx *);
|
||||
|
||||
void xu_ewmh_net_wm_desktop(struct client_ctx *);
|
||||
Atom *xu_ewmh_get_net_wm_state(struct client_ctx *, int *);
|
||||
void xu_ewmh_handle_net_wm_state_msg(struct client_ctx *,
|
||||
int, Atom, Atom);
|
||||
int, Atom , Atom);
|
||||
void xu_ewmh_set_net_wm_state(struct client_ctx *);
|
||||
void xu_ewmh_restore_net_wm_state(struct client_ctx *);
|
||||
|
||||
@ -626,7 +619,5 @@ char *xstrdup(const char *);
|
||||
int xasprintf(char **, const char *, ...)
|
||||
__attribute__((__format__ (printf, 2, 3)))
|
||||
__attribute__((__nonnull__ (2)));
|
||||
int xvasprintf(char **, const char *, va_list)
|
||||
__attribute__((__nonnull__ (2)));
|
||||
|
||||
#endif /* _CALMWM_H_ */
|
||||
|
395
client.c
395
client.c
@ -31,31 +31,34 @@
|
||||
|
||||
#include "calmwm.h"
|
||||
|
||||
static void client_class_hint(struct client_ctx *);
|
||||
static void client_placement(struct client_ctx *);
|
||||
static void client_mwm_hints(struct client_ctx *);
|
||||
static struct client_ctx *client_next(struct client_ctx *);
|
||||
static struct client_ctx *client_prev(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 *);
|
||||
|
||||
struct client_ctx *
|
||||
client_init(Window win, struct screen_ctx *sc)
|
||||
client_init(Window win, struct screen_ctx *sc, int active)
|
||||
{
|
||||
struct client_ctx *cc;
|
||||
XWindowAttributes wattr;
|
||||
int mapped;
|
||||
long state;
|
||||
Window rwin, cwin;
|
||||
int x, y, wx, wy;
|
||||
unsigned int mask;
|
||||
|
||||
if (win == None)
|
||||
return NULL;
|
||||
return(NULL);
|
||||
if (!XGetWindowAttributes(X_Dpy, win, &wattr))
|
||||
return NULL;
|
||||
return(NULL);
|
||||
|
||||
if (sc == NULL) {
|
||||
if ((sc = screen_find(wattr.root)) == NULL)
|
||||
return NULL;
|
||||
return(NULL);
|
||||
mapped = 1;
|
||||
} else {
|
||||
if (wattr.override_redirect || wattr.map_state != IsViewable)
|
||||
return NULL;
|
||||
return(NULL);
|
||||
mapped = wattr.map_state != IsUnmapped;
|
||||
}
|
||||
|
||||
@ -64,15 +67,12 @@ client_init(Window win, struct screen_ctx *sc)
|
||||
cc = xmalloc(sizeof(*cc));
|
||||
cc->sc = sc;
|
||||
cc->win = win;
|
||||
cc->name = NULL;
|
||||
cc->label = NULL;
|
||||
cc->gc = NULL;
|
||||
cc->res_class = NULL;
|
||||
cc->res_name = NULL;
|
||||
cc->flags = 0;
|
||||
cc->stackingorder = 0;
|
||||
cc->initial_state = 0;
|
||||
memset(&cc->hint, 0, sizeof(cc->hint));
|
||||
memset(&cc->ch, 0, sizeof(cc->ch));
|
||||
TAILQ_INIT(&cc->nameq);
|
||||
|
||||
cc->geom.x = wattr.x;
|
||||
@ -83,13 +83,13 @@ client_init(Window win, struct screen_ctx *sc)
|
||||
cc->obwidth = wattr.border_width;
|
||||
cc->bwidth = Conf.bwidth;
|
||||
|
||||
client_set_name(cc);
|
||||
client_setname(cc);
|
||||
conf_client(cc);
|
||||
|
||||
XGetClassHint(X_Dpy, cc->win, &cc->ch);
|
||||
client_wm_hints(cc);
|
||||
client_class_hint(cc);
|
||||
client_wm_protocols(cc);
|
||||
client_get_sizehints(cc);
|
||||
client_getsizehints(cc);
|
||||
client_transient(cc);
|
||||
client_mwm_hints(cc);
|
||||
|
||||
@ -101,14 +101,18 @@ client_init(Window win, struct screen_ctx *sc)
|
||||
cc->ptr.y = cc->geom.h / 2;
|
||||
|
||||
if (wattr.map_state != IsViewable) {
|
||||
client_placement(cc);
|
||||
client_placecalc(cc);
|
||||
client_resize(cc, 0);
|
||||
if (cc->initial_state)
|
||||
xu_set_wm_state(cc->win, cc->initial_state);
|
||||
if ((cc->wmh) && (cc->wmh->flags & StateHint))
|
||||
client_set_wm_state(cc, cc->wmh->initial_state);
|
||||
} else {
|
||||
if ((active == 0) && (XQueryPointer(X_Dpy, cc->win, &rwin,
|
||||
&cwin, &x, &y, &wx, &wy, &mask)) && (cwin != None))
|
||||
active = 1;
|
||||
}
|
||||
|
||||
XSelectInput(X_Dpy, cc->win,
|
||||
EnterWindowMask | PropertyChangeMask | KeyReleaseMask);
|
||||
XSelectInput(X_Dpy, cc->win, ColormapChangeMask | EnterWindowMask |
|
||||
PropertyChangeMask | KeyReleaseMask);
|
||||
|
||||
XAddToSaveSet(X_Dpy, cc->win);
|
||||
|
||||
@ -121,8 +125,7 @@ client_init(Window win, struct screen_ctx *sc)
|
||||
xu_ewmh_net_client_list_stacking(sc);
|
||||
xu_ewmh_restore_net_wm_state(cc);
|
||||
|
||||
xu_get_wm_state(cc->win, &state);
|
||||
if (state == IconicState)
|
||||
if (client_get_wm_state(cc) == IconicState)
|
||||
client_hide(cc);
|
||||
else
|
||||
client_show(cc);
|
||||
@ -145,29 +148,10 @@ out:
|
||||
XSync(X_Dpy, False);
|
||||
XUngrabServer(X_Dpy);
|
||||
|
||||
return cc;
|
||||
}
|
||||
if (active)
|
||||
client_setactive(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;
|
||||
return(cc);
|
||||
}
|
||||
|
||||
struct client_ctx *
|
||||
@ -179,30 +163,10 @@ client_find(Window win)
|
||||
TAILQ_FOREACH(sc, &Screenq, entry) {
|
||||
TAILQ_FOREACH(cc, &sc->clientq, entry) {
|
||||
if (cc->win == win)
|
||||
return cc;
|
||||
return(cc);
|
||||
}
|
||||
}
|
||||
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));
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
@ -225,15 +189,18 @@ client_remove(struct client_ctx *cc)
|
||||
free(wn);
|
||||
}
|
||||
|
||||
free(cc->name);
|
||||
free(cc->label);
|
||||
free(cc->res_class);
|
||||
free(cc->res_name);
|
||||
if (cc->ch.res_class)
|
||||
XFree(cc->ch.res_class);
|
||||
if (cc->ch.res_name)
|
||||
XFree(cc->ch.res_name);
|
||||
if (cc->wmh)
|
||||
XFree(cc->wmh);
|
||||
|
||||
free(cc);
|
||||
}
|
||||
|
||||
void
|
||||
client_set_active(struct client_ctx *cc)
|
||||
client_setactive(struct client_ctx *cc)
|
||||
{
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
struct client_ctx *oldcc;
|
||||
@ -249,7 +216,7 @@ client_set_active(struct client_ctx *cc)
|
||||
RevertToPointerRoot, CurrentTime);
|
||||
}
|
||||
if (cc->flags & CLIENT_WM_TAKE_FOCUS)
|
||||
xu_send_clientmsg(cc->win, cwmh[WM_TAKE_FOCUS], Last_Event_Time);
|
||||
client_msg(cc, cwmh[WM_TAKE_FOCUS], Last_Event_Time);
|
||||
|
||||
if ((oldcc = client_current(sc)) != NULL) {
|
||||
oldcc->flags &= ~CLIENT_ACTIVE;
|
||||
@ -267,6 +234,28 @@ client_set_active(struct client_ctx *cc)
|
||||
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
|
||||
client_toggle_freeze(struct client_ctx *cc)
|
||||
{
|
||||
@ -327,7 +316,7 @@ client_toggle_fullscreen(struct client_ctx *cc)
|
||||
|
||||
area = screen_area(sc,
|
||||
cc->geom.x + cc->geom.w / 2,
|
||||
cc->geom.y + cc->geom.h / 2, 0);
|
||||
cc->geom.y + cc->geom.h / 2, CWM_NOGAP);
|
||||
|
||||
cc->bwidth = 0;
|
||||
cc->geom = area;
|
||||
@ -336,7 +325,6 @@ client_toggle_fullscreen(struct client_ctx *cc)
|
||||
resize:
|
||||
client_resize(cc, 0);
|
||||
xu_ewmh_set_net_wm_state(cc);
|
||||
client_ptr_inbound(cc, 1);
|
||||
}
|
||||
|
||||
void
|
||||
@ -366,7 +354,7 @@ client_toggle_maximize(struct client_ctx *cc)
|
||||
|
||||
area = screen_area(sc,
|
||||
cc->geom.x + cc->geom.w / 2,
|
||||
cc->geom.y + cc->geom.h / 2, 1);
|
||||
cc->geom.y + cc->geom.h / 2, CWM_GAP);
|
||||
|
||||
cc->geom.x = area.x;
|
||||
cc->geom.y = area.y;
|
||||
@ -377,7 +365,6 @@ client_toggle_maximize(struct client_ctx *cc)
|
||||
resize:
|
||||
client_resize(cc, 0);
|
||||
xu_ewmh_set_net_wm_state(cc);
|
||||
client_ptr_inbound(cc, 1);
|
||||
}
|
||||
|
||||
void
|
||||
@ -401,7 +388,7 @@ client_toggle_vmaximize(struct client_ctx *cc)
|
||||
|
||||
area = screen_area(sc,
|
||||
cc->geom.x + cc->geom.w / 2,
|
||||
cc->geom.y + cc->geom.h / 2, 1);
|
||||
cc->geom.y + cc->geom.h / 2, CWM_GAP);
|
||||
|
||||
cc->geom.y = area.y;
|
||||
cc->geom.h = area.h - (cc->bwidth * 2);
|
||||
@ -410,7 +397,6 @@ client_toggle_vmaximize(struct client_ctx *cc)
|
||||
resize:
|
||||
client_resize(cc, 0);
|
||||
xu_ewmh_set_net_wm_state(cc);
|
||||
client_ptr_inbound(cc, 1);
|
||||
}
|
||||
|
||||
void
|
||||
@ -434,7 +420,7 @@ client_toggle_hmaximize(struct client_ctx *cc)
|
||||
|
||||
area = screen_area(sc,
|
||||
cc->geom.x + cc->geom.w / 2,
|
||||
cc->geom.y + cc->geom.h / 2, 1);
|
||||
cc->geom.y + cc->geom.h / 2, CWM_GAP);
|
||||
|
||||
cc->geom.x = area.x;
|
||||
cc->geom.w = area.w - (cc->bwidth * 2);
|
||||
@ -443,7 +429,6 @@ client_toggle_hmaximize(struct client_ctx *cc)
|
||||
resize:
|
||||
client_resize(cc, 0);
|
||||
xu_ewmh_set_net_wm_state(cc);
|
||||
client_ptr_inbound(cc, 1);
|
||||
}
|
||||
|
||||
void
|
||||
@ -506,7 +491,7 @@ void
|
||||
client_ptr_inbound(struct client_ctx *cc, int getpos)
|
||||
{
|
||||
if (getpos)
|
||||
xu_ptr_get(cc->win, &cc->ptr.x, &cc->ptr.y);
|
||||
xu_ptr_getpos(cc->win, &cc->ptr.x, &cc->ptr.y);
|
||||
|
||||
if (cc->ptr.x < 0)
|
||||
cc->ptr.x = 0;
|
||||
@ -517,21 +502,21 @@ client_ptr_inbound(struct client_ctx *cc, int getpos)
|
||||
else if (cc->ptr.y > cc->geom.h - 1)
|
||||
cc->ptr.y = cc->geom.h - 1;
|
||||
|
||||
client_ptr_warp(cc);
|
||||
client_ptrwarp(cc);
|
||||
}
|
||||
|
||||
void
|
||||
client_ptr_warp(struct client_ctx *cc)
|
||||
client_ptrwarp(struct client_ctx *cc)
|
||||
{
|
||||
xu_ptr_set(cc->win, cc->ptr.x, cc->ptr.y);
|
||||
xu_ptr_setpos(cc->win, cc->ptr.x, cc->ptr.y);
|
||||
}
|
||||
|
||||
void
|
||||
client_ptr_save(struct client_ctx *cc)
|
||||
client_ptrsave(struct client_ctx *cc)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
xu_ptr_get(cc->win, &x, &y);
|
||||
xu_ptr_getpos(cc->win, &x, &y);
|
||||
if (client_inbound(cc, x, y)) {
|
||||
cc->ptr.x = x;
|
||||
cc->ptr.y = y;
|
||||
@ -551,7 +536,7 @@ client_hide(struct client_ctx *cc)
|
||||
xu_ewmh_net_active_window(cc->sc, None);
|
||||
}
|
||||
cc->flags |= CLIENT_HIDDEN;
|
||||
xu_set_wm_state(cc->win, IconicState);
|
||||
client_set_wm_state(cc, IconicState);
|
||||
}
|
||||
|
||||
void
|
||||
@ -560,7 +545,7 @@ client_show(struct client_ctx *cc)
|
||||
XMapRaised(X_Dpy, cc->win);
|
||||
|
||||
cc->flags &= ~CLIENT_HIDDEN;
|
||||
xu_set_wm_state(cc->win, NormalState);
|
||||
client_set_wm_state(cc, NormalState);
|
||||
client_draw_border(cc);
|
||||
}
|
||||
|
||||
@ -596,24 +581,7 @@ client_draw_border(struct client_ctx *cc)
|
||||
pixel = sc->xftcolor[CWM_COLOR_BORDER_URGENCY].pixel;
|
||||
|
||||
XSetWindowBorderWidth(X_Dpy, cc->win, (unsigned int)cc->bwidth);
|
||||
XSetWindowBorder(X_Dpy, cc->win, pixel | (0xffu << 24));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
XSetWindowBorder(X_Dpy, cc->win, pixel);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -636,62 +604,149 @@ client_wm_protocols(struct client_ctx *cc)
|
||||
void
|
||||
client_wm_hints(struct client_ctx *cc)
|
||||
{
|
||||
XWMHints *wmh;
|
||||
if ((cc->wmh = XGetWMHints(X_Dpy, cc->win)) == NULL)
|
||||
return;
|
||||
|
||||
if ((wmh = XGetWMHints(X_Dpy, cc->win)) != NULL) {
|
||||
if ((wmh->flags & InputHint) && (wmh->input))
|
||||
cc->flags |= CLIENT_INPUT;
|
||||
if ((wmh->flags & XUrgencyHint))
|
||||
client_urgency(cc);
|
||||
if ((wmh->flags & StateHint))
|
||||
cc->initial_state = wmh->initial_state;
|
||||
XFree(wmh);
|
||||
}
|
||||
if ((cc->wmh->flags & InputHint) && (cc->wmh->input))
|
||||
cc->flags |= CLIENT_INPUT;
|
||||
|
||||
if ((cc->wmh->flags & XUrgencyHint))
|
||||
client_urgency(cc);
|
||||
}
|
||||
|
||||
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
|
||||
client_close(struct client_ctx *cc)
|
||||
{
|
||||
if (cc->flags & CLIENT_WM_DELETE_WINDOW)
|
||||
xu_send_clientmsg(cc->win, cwmh[WM_DELETE_WINDOW], CurrentTime);
|
||||
client_msg(cc, cwmh[WM_DELETE_WINDOW], CurrentTime);
|
||||
else
|
||||
XKillClient(X_Dpy, cc->win);
|
||||
}
|
||||
|
||||
void
|
||||
client_set_name(struct client_ctx *cc)
|
||||
client_setname(struct client_ctx *cc)
|
||||
{
|
||||
struct winname *wn, *wnnxt;
|
||||
struct winname *wn;
|
||||
char *newname;
|
||||
int i = 0;
|
||||
|
||||
free(cc->name);
|
||||
if (!xu_get_strprop(cc->win, ewmh[_NET_WM_NAME], &cc->name))
|
||||
if (!xu_get_strprop(cc->win, XA_WM_NAME, &cc->name))
|
||||
cc->name = xstrdup("");
|
||||
if (!xu_getstrprop(cc->win, ewmh[_NET_WM_NAME], &newname))
|
||||
if (!xu_getstrprop(cc->win, XA_WM_NAME, &newname))
|
||||
newname = xstrdup("");
|
||||
|
||||
TAILQ_FOREACH_SAFE(wn, &cc->nameq, entry, wnnxt) {
|
||||
if (strcmp(wn->name, cc->name) == 0) {
|
||||
TAILQ_FOREACH(wn, &cc->nameq, entry) {
|
||||
if (strcmp(wn->name, newname) == 0) {
|
||||
/* Move to the last since we got a hit. */
|
||||
TAILQ_REMOVE(&cc->nameq, wn, entry);
|
||||
free(wn->name);
|
||||
free(wn);
|
||||
TAILQ_INSERT_TAIL(&cc->nameq, wn, entry);
|
||||
goto match;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
wn = xmalloc(sizeof(*wn));
|
||||
wn->name = xstrdup(cc->name);
|
||||
wn->name = newname;
|
||||
TAILQ_INSERT_TAIL(&cc->nameq, wn, entry);
|
||||
match:
|
||||
cc->name = wn->name;
|
||||
|
||||
/* Garbage collection. */
|
||||
if ((i + 1) > Conf.nameqlen) {
|
||||
/* Do some garbage collection. */
|
||||
TAILQ_FOREACH(wn, &cc->nameq, entry)
|
||||
i++;
|
||||
if (i > Conf.nameqlen) {
|
||||
wn = TAILQ_FIRST(&cc->nameq);
|
||||
TAILQ_REMOVE(&cc->nameq, wn, entry);
|
||||
free(wn->name);
|
||||
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
|
||||
client_placement(struct client_ctx *cc)
|
||||
client_placecalc(struct client_ctx *cc)
|
||||
{
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
|
||||
@ -714,8 +769,8 @@ client_placement(struct client_ctx *cc)
|
||||
struct geom area;
|
||||
int xmouse, ymouse, xslack, yslack;
|
||||
|
||||
xu_ptr_get(sc->rootwin, &xmouse, &ymouse);
|
||||
area = screen_area(sc, xmouse, ymouse, 1);
|
||||
xu_ptr_getpos(sc->rootwin, &xmouse, &ymouse);
|
||||
area = screen_area(sc, xmouse, ymouse, CWM_GAP);
|
||||
|
||||
xmouse = MAX(MAX(xmouse, area.x) - cc->geom.w / 2, area.x);
|
||||
ymouse = MAX(MAX(ymouse, area.y) - cc->geom.h / 2, area.y);
|
||||
@ -748,7 +803,7 @@ client_mtf(struct client_ctx *cc)
|
||||
}
|
||||
|
||||
void
|
||||
client_get_sizehints(struct client_ctx *cc)
|
||||
client_getsizehints(struct client_ctx *cc)
|
||||
{
|
||||
long tmp;
|
||||
XSizeHints size;
|
||||
@ -796,7 +851,7 @@ client_get_sizehints(struct client_ctx *cc)
|
||||
}
|
||||
|
||||
void
|
||||
client_apply_sizehints(struct client_ctx *cc)
|
||||
client_applysizehints(struct client_ctx *cc)
|
||||
{
|
||||
Bool baseismin;
|
||||
|
||||
@ -847,17 +902,15 @@ client_mwm_hints(struct client_ctx *cc)
|
||||
{
|
||||
struct mwm_hints *mwmh;
|
||||
|
||||
if (xu_get_prop(cc->win, cwmh[_MOTIF_WM_HINTS],
|
||||
if (xu_getprop(cc->win, cwmh[_MOTIF_WM_HINTS],
|
||||
cwmh[_MOTIF_WM_HINTS], MWM_HINTS_ELEMENTS,
|
||||
(unsigned char **)&mwmh) <= 0)
|
||||
return;
|
||||
|
||||
if ((mwmh->flags & MWM_HINTS_DECORATIONS) &&
|
||||
!(mwmh->decorations & MWM_DECOR_ALL)) {
|
||||
if (!(mwmh->decorations & MWM_DECOR_BORDER))
|
||||
(unsigned char **)&mwmh) == MWM_HINTS_ELEMENTS) {
|
||||
if (mwmh->flags & MWM_FLAGS_DECORATIONS &&
|
||||
!(mwmh->decorations & MWM_DECOR_ALL) &&
|
||||
!(mwmh->decorations & MWM_DECOR_BORDER))
|
||||
cc->bwidth = 0;
|
||||
XFree(mwmh);
|
||||
}
|
||||
XFree(mwmh);
|
||||
}
|
||||
|
||||
void
|
||||
@ -899,15 +952,15 @@ client_snapcalc(int n0, int n1, int e0, int e1, int snapdist)
|
||||
/* possible to snap in both directions */
|
||||
if (s0 != 0 && s1 != 0)
|
||||
if (abs(s0) < abs(s1))
|
||||
return s0;
|
||||
return(s0);
|
||||
else
|
||||
return s1;
|
||||
return(s1);
|
||||
else if (s0 != 0)
|
||||
return s0;
|
||||
return(s0);
|
||||
else if (s1 != 0)
|
||||
return s1;
|
||||
return(s1);
|
||||
else
|
||||
return 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
void
|
||||
@ -918,10 +971,13 @@ client_htile(struct client_ctx *cc)
|
||||
struct geom area;
|
||||
int i, n, mh, x, w, h;
|
||||
|
||||
if (!cc->gc)
|
||||
return;
|
||||
i = n = 0;
|
||||
|
||||
area = screen_area(sc,
|
||||
cc->geom.x + cc->geom.w / 2,
|
||||
cc->geom.y + cc->geom.h / 2, 1);
|
||||
cc->geom.y + cc->geom.h / 2, CWM_GAP);
|
||||
|
||||
TAILQ_FOREACH(ci, &sc->clientq, entry) {
|
||||
if (ci->gc != cc->gc)
|
||||
@ -946,10 +1002,9 @@ client_htile(struct client_ctx *cc)
|
||||
cc->geom.x = area.x;
|
||||
cc->geom.y = area.y;
|
||||
cc->geom.w = area.w - (cc->bwidth * 2);
|
||||
if (Conf.htile > 0)
|
||||
cc->geom.h = ((area.h - (cc->bwidth * 2)) * Conf.htile) / 100;
|
||||
cc->geom.h = (area.h - (cc->bwidth * 2)) / 2;
|
||||
client_resize(cc, 1);
|
||||
client_ptr_warp(cc);
|
||||
client_ptrwarp(cc);
|
||||
|
||||
mh = cc->geom.h + (cc->bwidth * 2);
|
||||
x = area.x;
|
||||
@ -987,10 +1042,13 @@ client_vtile(struct client_ctx *cc)
|
||||
struct geom area;
|
||||
int i, n, mw, y, w, h;
|
||||
|
||||
if (!cc->gc)
|
||||
return;
|
||||
i = n = 0;
|
||||
|
||||
area = screen_area(sc,
|
||||
cc->geom.x + cc->geom.w / 2,
|
||||
cc->geom.y + cc->geom.h / 2, 1);
|
||||
cc->geom.y + cc->geom.h / 2, CWM_GAP);
|
||||
|
||||
TAILQ_FOREACH(ci, &sc->clientq, entry) {
|
||||
if (ci->gc != cc->gc)
|
||||
@ -1014,11 +1072,10 @@ client_vtile(struct client_ctx *cc)
|
||||
cc->flags &= ~CLIENT_VMAXIMIZED;
|
||||
cc->geom.x = area.x;
|
||||
cc->geom.y = area.y;
|
||||
if (Conf.vtile > 0)
|
||||
cc->geom.w = ((area.w - (cc->bwidth * 2)) * Conf.vtile) / 100;
|
||||
cc->geom.w = (area.w - (cc->bwidth * 2)) / 2;
|
||||
cc->geom.h = area.h - (cc->bwidth * 2);
|
||||
client_resize(cc, 1);
|
||||
client_ptr_warp(cc);
|
||||
client_ptrwarp(cc);
|
||||
|
||||
mw = cc->geom.w + (cc->bwidth * 2);
|
||||
y = area.y;
|
||||
@ -1047,3 +1104,25 @@ client_vtile(struct client_ctx *cc)
|
||||
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);
|
||||
}
|
||||
|
82
conf.c
82
conf.c
@ -32,7 +32,7 @@
|
||||
|
||||
#include "calmwm.h"
|
||||
|
||||
static const char *conf_bind_mask(const char *, unsigned int *);
|
||||
static const char *conf_bind_getmask(const char *, unsigned int *);
|
||||
static void conf_unbind_key(struct conf *, struct bind_ctx *);
|
||||
static void conf_unbind_mouse(struct conf *, struct bind_ctx *);
|
||||
|
||||
@ -139,7 +139,6 @@ static const struct {
|
||||
|
||||
{ FUNC_SC(group-cycle, group_cycle, (CWM_CYCLE_FORWARD)) },
|
||||
{ FUNC_SC(group-rcycle, group_cycle, (CWM_CYCLE_REVERSE)) },
|
||||
{ FUNC_SC(group-last, group_last, 0) },
|
||||
{ FUNC_SC(group-toggle-all, group_toggle_all, 0) },
|
||||
{ FUNC_SC(group-toggle-1, group_toggle, 1) },
|
||||
{ FUNC_SC(group-toggle-2, group_toggle, 2) },
|
||||
@ -198,11 +197,10 @@ static const struct {
|
||||
const char ch;
|
||||
int mask;
|
||||
} bind_mods[] = {
|
||||
{ 'S', ShiftMask },
|
||||
{ 'C', ControlMask },
|
||||
{ 'M', Mod1Mask },
|
||||
{ '4', Mod4Mask },
|
||||
{ '5', Mod5Mask },
|
||||
{ 'S', ShiftMask },
|
||||
};
|
||||
static const struct {
|
||||
const char *key;
|
||||
@ -282,8 +280,6 @@ conf_init(struct conf *c)
|
||||
c->stickygroups = 0;
|
||||
c->bwidth = 1;
|
||||
c->mamount = 1;
|
||||
c->htile = 50;
|
||||
c->vtile = 50;
|
||||
c->snapdist = 0;
|
||||
c->ngroups = 0;
|
||||
c->nameqlen = 5;
|
||||
@ -520,7 +516,7 @@ conf_group(struct screen_ctx *sc)
|
||||
}
|
||||
|
||||
static const char *
|
||||
conf_bind_mask(const char *name, unsigned int *mask)
|
||||
conf_bind_getmask(const char *name, unsigned int *mask)
|
||||
{
|
||||
char *dash;
|
||||
const char *ch;
|
||||
@ -528,13 +524,13 @@ conf_bind_mask(const char *name, unsigned int *mask)
|
||||
|
||||
*mask = 0;
|
||||
if ((dash = strchr(name, '-')) == NULL)
|
||||
return name;
|
||||
return(name);
|
||||
for (i = 0; i < nitems(bind_mods); i++) {
|
||||
if ((ch = strchr(name, bind_mods[i].ch)) != NULL && ch < dash)
|
||||
*mask |= bind_mods[i].mask;
|
||||
}
|
||||
/* Skip past modifiers. */
|
||||
return (dash + 1);
|
||||
return(dash + 1);
|
||||
}
|
||||
|
||||
int
|
||||
@ -547,20 +543,20 @@ conf_bind_key(struct conf *c, const char *bind, const char *cmd)
|
||||
|
||||
if ((strcmp(bind, "all") == 0) && (cmd == NULL)) {
|
||||
conf_unbind_key(c, NULL);
|
||||
return 1;
|
||||
return(1);
|
||||
}
|
||||
kb = xmalloc(sizeof(*kb));
|
||||
key = conf_bind_mask(bind, &kb->modmask);
|
||||
key = conf_bind_getmask(bind, &kb->modmask);
|
||||
kb->press.keysym = XStringToKeysym(key);
|
||||
if (kb->press.keysym == NoSymbol) {
|
||||
warnx("unknown symbol: %s", key);
|
||||
free(kb);
|
||||
return 0;
|
||||
return(0);
|
||||
}
|
||||
conf_unbind_key(c, kb);
|
||||
if (cmd == NULL) {
|
||||
free(kb);
|
||||
return 1;
|
||||
return(1);
|
||||
}
|
||||
cargs = xcalloc(1, sizeof(*cargs));
|
||||
for (i = 0; i < nitems(name_to_func); i++) {
|
||||
@ -578,7 +574,7 @@ conf_bind_key(struct conf *c, const char *bind, const char *cmd)
|
||||
out:
|
||||
kb->cargs = cargs;
|
||||
TAILQ_INSERT_TAIL(&c->keybindq, kb, entry);
|
||||
return 1;
|
||||
return(1);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -608,20 +604,20 @@ conf_bind_mouse(struct conf *c, const char *bind, const char *cmd)
|
||||
|
||||
if ((strcmp(bind, "all") == 0) && (cmd == NULL)) {
|
||||
conf_unbind_mouse(c, NULL);
|
||||
return 1;
|
||||
return(1);
|
||||
}
|
||||
mb = xmalloc(sizeof(*mb));
|
||||
button = conf_bind_mask(bind, &mb->modmask);
|
||||
button = conf_bind_getmask(bind, &mb->modmask);
|
||||
mb->press.button = strtonum(button, Button1, Button5, &errstr);
|
||||
if (errstr) {
|
||||
warnx("button number is %s: %s", errstr, button);
|
||||
free(mb);
|
||||
return 0;
|
||||
return(0);
|
||||
}
|
||||
conf_unbind_mouse(c, mb);
|
||||
if (cmd == NULL) {
|
||||
free(mb);
|
||||
return 1;
|
||||
return(1);
|
||||
}
|
||||
cargs = xcalloc(1, sizeof(*cargs));
|
||||
for (i = 0; i < nitems(name_to_func); i++) {
|
||||
@ -639,7 +635,7 @@ conf_bind_mouse(struct conf *c, const char *bind, const char *cmd)
|
||||
out:
|
||||
mb->cargs = cargs;
|
||||
TAILQ_INSERT_TAIL(&c->mousebindq, mb, entry);
|
||||
return 1;
|
||||
return(1);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -648,7 +644,7 @@ conf_unbind_mouse(struct conf *c, struct bind_ctx *unbind)
|
||||
struct bind_ctx *mb = NULL, *mbnxt;
|
||||
|
||||
TAILQ_FOREACH_SAFE(mb, &c->mousebindq, entry, mbnxt) {
|
||||
if ((unbind == NULL) ||
|
||||
if ((unbind == NULL) ||
|
||||
((mb->modmask == unbind->modmask) &&
|
||||
(mb->press.button == unbind->press.button))) {
|
||||
TAILQ_REMOVE(&c->mousebindq, mb, entry);
|
||||
@ -670,8 +666,6 @@ conf_grab_kbd(Window win)
|
||||
|
||||
TAILQ_FOREACH(kb, &Conf.keybindq, entry) {
|
||||
kc = XKeysymToKeycode(X_Dpy, kb->press.keysym);
|
||||
if (kc == 0)
|
||||
continue;
|
||||
if ((XkbKeycodeToKeysym(X_Dpy, kc, 0, 0) != kb->press.keysym) &&
|
||||
(XkbKeycodeToKeysym(X_Dpy, kc, 0, 1) == kb->press.keysym))
|
||||
kb->modmask |= ShiftMask;
|
||||
@ -701,3 +695,47 @@ 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);
|
||||
}
|
||||
|
69
cwmrc.5
69
cwmrc.5
@ -37,8 +37,10 @@ Arguments containing whitespace should be surrounded by double quotes
|
||||
.Pq \&" .
|
||||
.Pp
|
||||
The following options are accepted:
|
||||
.Bl -tag -width Ds
|
||||
.It Ic autogroup Ar group Oo Ar windowname , Oc Ns Ar windowclass
|
||||
.Pp
|
||||
.Bl -tag -width Ds -compact
|
||||
.It Ic autogroup Ar group windowclass
|
||||
.It Ic autogroup Ar group windowname,windowclass
|
||||
Automatically add new windows to
|
||||
.Ar group
|
||||
if their class property matches
|
||||
@ -60,6 +62,7 @@ used to override
|
||||
The name and class values, respectively, for existing windows
|
||||
are both set in the WM_CLASS property and may be obtained using
|
||||
.Xr xprop 1 .
|
||||
.Pp
|
||||
.It Ic bind-key Ar key function
|
||||
Bind or rebind key
|
||||
.Ar key
|
||||
@ -81,8 +84,6 @@ Meta key.
|
||||
Shift key.
|
||||
.It Ic 4
|
||||
Mod4 (windows) key.
|
||||
.It Ic 5
|
||||
Mod5 (AltGr) key.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
@ -90,6 +91,7 @@ The
|
||||
may either be one from the
|
||||
.Sx BIND FUNCTION LIST
|
||||
(see below) or the command line that is to be executed.
|
||||
.Pp
|
||||
.It Ic bind-mouse Ar button function
|
||||
Bind or rebind button
|
||||
.Ar button
|
||||
@ -99,10 +101,18 @@ The modifier keys come first, followed by a
|
||||
.Sq - ,
|
||||
then the button number.
|
||||
.Pp
|
||||
The same modifiers are recognised as for
|
||||
.Ar key
|
||||
in
|
||||
.Nm bind-key .
|
||||
The following modifiers are recognised:
|
||||
.Pp
|
||||
.Bl -tag -width Ds -offset indent -compact
|
||||
.It Ic C
|
||||
Control key.
|
||||
.It Ic M
|
||||
Meta key.
|
||||
.It Ic S
|
||||
Shift key.
|
||||
.It Ic 4
|
||||
Mod4 (windows) key.
|
||||
.El
|
||||
.Pp
|
||||
The following buttons are recognised:
|
||||
.Pp
|
||||
@ -124,27 +134,38 @@ The
|
||||
may be taken from the
|
||||
.Sx BIND FUNCTION LIST
|
||||
(see below) or the command line that is to be executed.
|
||||
.Pp
|
||||
.It Ic borderwidth Ar pixels
|
||||
Set the window border width to
|
||||
.Ar pixels .
|
||||
.Pp
|
||||
.It Ic color activeborder Ar color
|
||||
Set the color of the active border.
|
||||
.Pp
|
||||
.It Ic color font Ar color
|
||||
Set menu font color.
|
||||
.Pp
|
||||
.It Ic color selfont Ar color
|
||||
Set font color for selected menu item.
|
||||
.Pp
|
||||
.It Ic color groupborder Ar color
|
||||
Set the color of the border while grouping a window.
|
||||
.Pp
|
||||
.It Ic color inactiveborder Ar color
|
||||
Set the color of the inactive border.
|
||||
.Pp
|
||||
.It Ic color menubg Ar color
|
||||
Set menu background color.
|
||||
.Pp
|
||||
.It Ic color menufg Ar color
|
||||
Set menu foreground color.
|
||||
.Pp
|
||||
.It Ic color urgencyborder Ar color
|
||||
Set the color of the border of a window indicating urgency.
|
||||
.Pp
|
||||
.It Ic color ungroupborder Ar color
|
||||
Set the color of the border while ungrouping a window.
|
||||
.Pp
|
||||
.It Ic command Ar name path
|
||||
Every
|
||||
.Ar name
|
||||
@ -168,11 +189,13 @@ The defaults are
|
||||
and
|
||||
.Xr xlock 1 ,
|
||||
respectively.
|
||||
.Pp
|
||||
.It Ic fontname Ar font
|
||||
Change the default
|
||||
.Ar font
|
||||
for
|
||||
.Xr Xft 3 .
|
||||
.Pp
|
||||
.It Ic gap Ar top bottom left right
|
||||
Define a
|
||||
.Dq gap
|
||||
@ -183,30 +206,28 @@ This
|
||||
can be used for applications such as
|
||||
.Xr xclock 1 ,
|
||||
where the user may wish to remain visible.
|
||||
.It Ic htile Ar percent
|
||||
Set the percentage of screen the master window should occupy
|
||||
after calling
|
||||
.Ic window-htile .
|
||||
If set to 0, the horizontal size of the master window will
|
||||
remain unchanged.
|
||||
The default is 50.
|
||||
.Pp
|
||||
.It Ic ignore Ar windowname
|
||||
Ignore, and do not warp to, windows with the name
|
||||
.Ar windowname
|
||||
when drawing borders and cycling through windows.
|
||||
.Pp
|
||||
.It Ic moveamount Ar pixels
|
||||
Set a default size for the keyboard movement bindings,
|
||||
in pixels.
|
||||
The default is 1.
|
||||
.Pp
|
||||
.It Ic snapdist Ar pixels
|
||||
Minimum distance to snap-to adjacent edge, in pixels.
|
||||
The default is 0.
|
||||
.Pp
|
||||
.It Ic sticky Ic yes Ns \&| Ns Ic no
|
||||
Toggle sticky group mode.
|
||||
The default behavior for new windows is to not assign any group.
|
||||
By enabling sticky group mode,
|
||||
.Xr cwm 1
|
||||
will assign new windows to the currently selected group.
|
||||
.Pp
|
||||
.It Ic unbind-key Ar key
|
||||
Unbind function bound to
|
||||
.Ar key .
|
||||
@ -215,6 +236,7 @@ A special
|
||||
keyword
|
||||
.Dq all
|
||||
can be used to unbind all keys.
|
||||
.Pp
|
||||
.It Ic unbind-mouse Ar button
|
||||
Unbind function bound to
|
||||
.Ar button .
|
||||
@ -223,13 +245,6 @@ A special
|
||||
keyword
|
||||
.Dq all
|
||||
can be used to unbind all buttons.
|
||||
.It Ic vtile Ar percent
|
||||
Set the percentage of screen the master window should occupy
|
||||
after calling
|
||||
.Ic window-vtile .
|
||||
If set to 0, the vertical size of the master window will
|
||||
remain unchanged.
|
||||
The default is 50.
|
||||
.It Ic wm Ar name path
|
||||
Every
|
||||
.Ar name
|
||||
@ -273,8 +288,6 @@ menu.
|
||||
Toggle visibility of group n, where n is 1-9.
|
||||
.It group-only-[n]
|
||||
Show only group n, where n is 1-9, hiding other groups.
|
||||
.It group-last
|
||||
Show only the previously active group.
|
||||
.It group-close-[n]
|
||||
Close all windows in group n, where n is 1-9.
|
||||
.It group-toggle-all
|
||||
@ -319,15 +332,11 @@ Vertically maximize current window (gap + border honored).
|
||||
Horizontally maximize current window (gap + border honored).
|
||||
.It window-htile
|
||||
Current window is placed at the top of the screen, maximized
|
||||
horizontally and resized to
|
||||
.Ar htile
|
||||
(default half) of the vertical screen space.
|
||||
horizontally and resized to half of the vertical screen space.
|
||||
Other windows in its group share remaining screen space.
|
||||
.It window-vtile
|
||||
Current window is placed on the left of the screen, maximized vertically
|
||||
and resized to
|
||||
.Ar vtile
|
||||
(default half) of the horizontal screen space.
|
||||
and resized to half of the horizontal screen space.
|
||||
Other windows in its group share remaining screen space.
|
||||
.It window-move
|
||||
Move current window.
|
||||
|
49
group.c
49
group.c
@ -35,7 +35,7 @@
|
||||
static struct group_ctx *group_next(struct group_ctx *);
|
||||
static struct group_ctx *group_prev(struct group_ctx *);
|
||||
static void group_restack(struct group_ctx *);
|
||||
static void group_set_active(struct group_ctx *);
|
||||
static void group_setactive(struct group_ctx *);
|
||||
|
||||
void
|
||||
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;
|
||||
|
||||
xu_ewmh_set_net_wm_desktop(cc);
|
||||
xu_ewmh_net_wm_desktop(cc);
|
||||
}
|
||||
|
||||
void
|
||||
@ -79,7 +79,7 @@ group_show(struct group_ctx *gc)
|
||||
client_show(cc);
|
||||
}
|
||||
group_restack(gc);
|
||||
group_set_active(gc);
|
||||
group_setactive(gc);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -134,11 +134,11 @@ group_init(struct screen_ctx *sc, int num, const char *name)
|
||||
TAILQ_INSERT_TAIL(&sc->groupq, gc, entry);
|
||||
|
||||
if (num == 1)
|
||||
group_set_active(gc);
|
||||
group_setactive(gc);
|
||||
}
|
||||
|
||||
void
|
||||
group_set_active(struct group_ctx *gc)
|
||||
group_setactive(struct group_ctx *gc)
|
||||
{
|
||||
struct screen_ctx *sc = gc->sc;
|
||||
|
||||
@ -190,9 +190,9 @@ group_holds_only_sticky(struct group_ctx *gc)
|
||||
if (cc->gc != gc)
|
||||
continue;
|
||||
if (!(cc->flags & CLIENT_STICKY))
|
||||
return 0;
|
||||
return(0);
|
||||
}
|
||||
return 1;
|
||||
return(1);
|
||||
}
|
||||
|
||||
int
|
||||
@ -205,9 +205,9 @@ group_holds_only_hidden(struct group_ctx *gc)
|
||||
if (cc->gc != gc)
|
||||
continue;
|
||||
if (!(cc->flags & (CLIENT_HIDDEN | CLIENT_STICKY)))
|
||||
return 0;
|
||||
return(0);
|
||||
}
|
||||
return 1;
|
||||
return(1);
|
||||
}
|
||||
|
||||
void
|
||||
@ -215,9 +215,6 @@ group_only(struct screen_ctx *sc, int idx)
|
||||
{
|
||||
struct group_ctx *gc;
|
||||
|
||||
if (sc->group_last != sc->group_active)
|
||||
sc->group_last = sc->group_active;
|
||||
|
||||
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
||||
if (gc->num == idx)
|
||||
group_show(gc);
|
||||
@ -300,7 +297,7 @@ group_cycle(struct screen_ctx *sc, int flags)
|
||||
if (group_holds_only_hidden(showgroup))
|
||||
group_show(showgroup);
|
||||
else
|
||||
group_set_active(showgroup);
|
||||
group_setactive(showgroup);
|
||||
}
|
||||
|
||||
static struct group_ctx *
|
||||
@ -329,21 +326,23 @@ group_restore(struct client_ctx *cc)
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
struct group_ctx *gc;
|
||||
int num;
|
||||
long grpnum;
|
||||
long *grpnum;
|
||||
|
||||
if (!xu_ewmh_get_net_wm_desktop(cc, &grpnum))
|
||||
return 0;
|
||||
if (xu_getprop(cc->win, ewmh[_NET_WM_DESKTOP], XA_CARDINAL, 1L,
|
||||
(unsigned char **)&grpnum) <= 0)
|
||||
return(0);
|
||||
|
||||
num = (grpnum == -1) ? 0 : grpnum;
|
||||
num = (*grpnum == -1) ? 0 : *grpnum;
|
||||
num = MIN(num, (Conf.ngroups - 1));
|
||||
XFree(grpnum);
|
||||
|
||||
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
||||
if (gc->num == num) {
|
||||
group_assign(gc, cc);
|
||||
return 1;
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
@ -354,13 +353,13 @@ group_autogroup(struct client_ctx *cc)
|
||||
struct group_ctx *gc;
|
||||
int num = -1, both_match = 0;
|
||||
|
||||
if (cc->res_class == NULL || cc->res_name == NULL)
|
||||
return 0;
|
||||
if (cc->ch.res_class == NULL || cc->ch.res_name == NULL)
|
||||
return(0);
|
||||
|
||||
TAILQ_FOREACH(ag, &Conf.autogroupq, entry) {
|
||||
if (strcmp(ag->class, cc->res_class) == 0) {
|
||||
if (strcmp(ag->class, cc->ch.res_class) == 0) {
|
||||
if ((ag->name != NULL) &&
|
||||
(strcmp(ag->name, cc->res_name) == 0)) {
|
||||
(strcmp(ag->name, cc->ch.res_name) == 0)) {
|
||||
num = ag->num;
|
||||
both_match = 1;
|
||||
} else if (ag->name == NULL && !both_match)
|
||||
@ -371,8 +370,8 @@ group_autogroup(struct client_ctx *cc)
|
||||
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
||||
if (gc->num == num) {
|
||||
group_assign(gc, cc);
|
||||
return 1;
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return(0);
|
||||
}
|
||||
|
99
kbfunc.c
99
kbfunc.c
@ -62,7 +62,7 @@ kbfunc_amount(int flags, int amt, int *mx, int *my)
|
||||
if (flags & CWM_BIGAMOUNT)
|
||||
amt *= CWM_FACTOR;
|
||||
|
||||
switch (flags & (CWM_UP | CWM_DOWN | CWM_LEFT | CWM_RIGHT)) {
|
||||
switch (flags & DIRECTIONMASK) {
|
||||
case CWM_UP:
|
||||
*my -= amt;
|
||||
break;
|
||||
@ -87,8 +87,8 @@ kbfunc_ptrmove(void *ctx, struct cargs *cargs)
|
||||
|
||||
kbfunc_amount(cargs->flag, Conf.mamount, &mx, &my);
|
||||
|
||||
xu_ptr_get(sc->rootwin, &x, &y);
|
||||
xu_ptr_set(sc->rootwin, x + mx, y + my);
|
||||
xu_ptr_getpos(sc->rootwin, &x, &y);
|
||||
xu_ptr_setpos(sc->rootwin, x + mx, y + my);
|
||||
}
|
||||
|
||||
void
|
||||
@ -135,7 +135,7 @@ kbfunc_client_move_kb(void *ctx, struct cargs *cargs)
|
||||
|
||||
area = screen_area(sc,
|
||||
cc->geom.x + cc->geom.w / 2,
|
||||
cc->geom.y + cc->geom.h / 2, 1);
|
||||
cc->geom.y + cc->geom.h / 2, CWM_GAP);
|
||||
cc->geom.x += client_snapcalc(cc->geom.x,
|
||||
cc->geom.x + cc->geom.w + (cc->bwidth * 2),
|
||||
area.x, area.x + area.w, sc->snapdist);
|
||||
@ -186,7 +186,7 @@ kbfunc_client_move_mb(void *ctx, struct cargs *cargs)
|
||||
|
||||
area = screen_area(sc,
|
||||
cc->geom.x + cc->geom.w / 2,
|
||||
cc->geom.y + cc->geom.h / 2, 1);
|
||||
cc->geom.y + cc->geom.h / 2, CWM_GAP);
|
||||
cc->geom.x += client_snapcalc(cc->geom.x,
|
||||
cc->geom.x + cc->geom.w + (cc->bwidth * 2),
|
||||
area.x, area.x + area.w, sc->snapdist);
|
||||
@ -250,9 +250,9 @@ kbfunc_client_resize_mb(void *ctx, struct cargs *cargs)
|
||||
return;
|
||||
|
||||
client_raise(cc);
|
||||
client_ptr_save(cc);
|
||||
client_ptrsave(cc);
|
||||
|
||||
xu_ptr_set(cc->win, cc->geom.w, cc->geom.h);
|
||||
xu_ptr_setpos(cc->win, cc->geom.w, cc->geom.h);
|
||||
|
||||
if (XGrabPointer(X_Dpy, cc->win, False, MOUSEMASK,
|
||||
GrabModeAsync, GrabModeAsync, None, Conf.cursor[CF_RESIZE],
|
||||
@ -272,7 +272,7 @@ kbfunc_client_resize_mb(void *ctx, struct cargs *cargs)
|
||||
|
||||
cc->geom.w = ev.xmotion.x;
|
||||
cc->geom.h = ev.xmotion.y;
|
||||
client_apply_sizehints(cc);
|
||||
client_applysizehints(cc);
|
||||
client_resize(cc, 1);
|
||||
screen_prop_win_draw(sc,
|
||||
"%4d x %-4d", cc->dim.w, cc->dim.h);
|
||||
@ -301,7 +301,7 @@ kbfunc_client_snap(void *ctx, struct cargs *cargs)
|
||||
|
||||
area = screen_area(sc,
|
||||
cc->geom.x + cc->geom.w / 2,
|
||||
cc->geom.y + cc->geom.h / 2, 1);
|
||||
cc->geom.y + cc->geom.h / 2, CWM_GAP);
|
||||
|
||||
flags = cargs->flag;
|
||||
while (flags) {
|
||||
@ -325,7 +325,6 @@ kbfunc_client_snap(void *ctx, struct cargs *cargs)
|
||||
}
|
||||
}
|
||||
client_move(cc);
|
||||
client_ptr_inbound(cc, 1);
|
||||
}
|
||||
|
||||
void
|
||||
@ -337,7 +336,7 @@ kbfunc_client_close(void *ctx, struct cargs *cargs)
|
||||
void
|
||||
kbfunc_client_lower(void *ctx, struct cargs *cargs)
|
||||
{
|
||||
client_ptr_save(ctx);
|
||||
client_ptrsave(ctx);
|
||||
client_lower(ctx);
|
||||
}
|
||||
|
||||
@ -405,64 +404,13 @@ void
|
||||
kbfunc_client_cycle(void *ctx, struct cargs *cargs)
|
||||
{
|
||||
struct screen_ctx *sc = ctx;
|
||||
struct client_ctx *newcc, *oldcc, *prevcc;
|
||||
int again = 1, flags = cargs->flag;
|
||||
|
||||
/* For X apps that ignore/steal events. */
|
||||
if (cargs->xev == CWM_XEV_KEY)
|
||||
XGrabKeyboard(X_Dpy, sc->rootwin, True,
|
||||
GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* When no client is active, warp pointer to last active. */
|
||||
if (oldcc->flags & (CLIENT_ACTIVE))
|
||||
client_ptr_warp(newcc);
|
||||
else if (oldcc->flags & (CLIENT_SKIP_CYCLE))
|
||||
client_ptr_warp(newcc);
|
||||
else {
|
||||
client_raise(oldcc);
|
||||
client_ptr_warp(oldcc);
|
||||
}
|
||||
client_cycle(sc, cargs->flag);
|
||||
}
|
||||
|
||||
void
|
||||
@ -490,14 +438,6 @@ kbfunc_group_only(void *ctx, struct cargs *cargs)
|
||||
group_only(ctx, cargs->flag);
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_group_last(void *ctx, struct cargs *cargs)
|
||||
{
|
||||
struct screen_ctx *sc = ctx;
|
||||
|
||||
group_only(ctx, sc->group_last->num);
|
||||
}
|
||||
|
||||
void
|
||||
kbfunc_group_toggle(void *ctx, struct cargs *cargs)
|
||||
{
|
||||
@ -529,15 +469,20 @@ kbfunc_menu_client(void *ctx, struct cargs *cargs)
|
||||
struct client_ctx *cc, *old_cc;
|
||||
struct menu *mi;
|
||||
struct menu_q menuq;
|
||||
int all = (cargs->flag & CWM_MENU_WINDOW_ALL);
|
||||
int mflags = 0;
|
||||
|
||||
if (cargs->xev == CWM_XEV_BTN)
|
||||
mflags |= CWM_MENU_LIST;
|
||||
|
||||
old_cc = client_current(sc);
|
||||
|
||||
TAILQ_INIT(&menuq);
|
||||
TAILQ_FOREACH(cc, &sc->clientq, entry) {
|
||||
if ((cargs->flag & CWM_MENU_WINDOW_ALL) ||
|
||||
(cc->flags & CLIENT_HIDDEN))
|
||||
if (!all) {
|
||||
if (cc->flags & CLIENT_HIDDEN)
|
||||
menuq_add(&menuq, cc, NULL);
|
||||
} else
|
||||
menuq_add(&menuq, cc, NULL);
|
||||
}
|
||||
|
||||
@ -545,9 +490,9 @@ kbfunc_menu_client(void *ctx, struct cargs *cargs)
|
||||
search_match_client, search_print_client)) != NULL) {
|
||||
cc = (struct client_ctx *)mi->ctx;
|
||||
client_show(cc);
|
||||
if ((old_cc = client_current(sc)) != NULL)
|
||||
client_ptr_save(old_cc);
|
||||
client_ptr_warp(cc);
|
||||
if (old_cc)
|
||||
client_ptrsave(old_cc);
|
||||
client_ptrwarp(cc);
|
||||
}
|
||||
|
||||
menuq_clear(&menuq);
|
||||
@ -680,7 +625,7 @@ kbfunc_menu_exec(void *ctx, struct cargs *cargs)
|
||||
/* lstat(2) in case d_type isn't supported. */
|
||||
if (lstat(tpath, &sb) == -1)
|
||||
continue;
|
||||
if (!S_ISREG(sb.st_mode) &&
|
||||
if (!S_ISREG(sb.st_mode) &&
|
||||
!S_ISLNK(sb.st_mode))
|
||||
continue;
|
||||
}
|
||||
|
61
menu.c
61
menu.c
@ -94,7 +94,7 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, const char *prompt,
|
||||
|
||||
TAILQ_INIT(&resultq);
|
||||
|
||||
xu_ptr_get(sc->rootwin, &xsave, &ysave);
|
||||
xu_ptr_getpos(sc->rootwin, &xsave, &ysave);
|
||||
|
||||
(void)memset(&mc, 0, sizeof(mc));
|
||||
mc.sc = sc;
|
||||
@ -129,7 +129,7 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, const char *prompt,
|
||||
CurrentTime) != GrabSuccess) {
|
||||
XftDrawDestroy(mc.xftdraw);
|
||||
XDestroyWindow(X_Dpy, mc.win);
|
||||
return NULL;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
XGetInputFocus(X_Dpy, &focuswin, &focusrevert);
|
||||
@ -178,14 +178,14 @@ out:
|
||||
|
||||
XSetInputFocus(X_Dpy, focuswin, focusrevert, CurrentTime);
|
||||
/* restore if user didn't move */
|
||||
xu_ptr_get(sc->rootwin, &xcur, &ycur);
|
||||
xu_ptr_getpos(sc->rootwin, &xcur, &ycur);
|
||||
if (xcur == mc.geom.x && ycur == mc.geom.y)
|
||||
xu_ptr_set(sc->rootwin, xsave, ysave);
|
||||
xu_ptr_setpos(sc->rootwin, xsave, ysave);
|
||||
|
||||
XUngrabPointer(X_Dpy, CurrentTime);
|
||||
XUngrabKeyboard(X_Dpy, CurrentTime);
|
||||
|
||||
return mi;
|
||||
return(mi);
|
||||
}
|
||||
|
||||
static struct menu *
|
||||
@ -213,7 +213,7 @@ menu_complete_path(struct menu_ctx *mc)
|
||||
|
||||
menuq_clear(&menuq);
|
||||
|
||||
return mr;
|
||||
return(mr);
|
||||
}
|
||||
|
||||
static struct menu *
|
||||
@ -228,7 +228,7 @@ menu_handle_key(XEvent *e, struct menu_ctx *mc, struct menu_q *menuq,
|
||||
wchar_t wc;
|
||||
|
||||
if (menu_keycode(&e->xkey, &ctl, chr) < 0)
|
||||
return NULL;
|
||||
return(NULL);
|
||||
|
||||
switch (ctl) {
|
||||
case CTL_ERASEONE:
|
||||
@ -269,7 +269,7 @@ menu_handle_key(XEvent *e, struct menu_ctx *mc, struct menu_q *menuq,
|
||||
mi->dummy = 1;
|
||||
}
|
||||
mi->abort = 0;
|
||||
return mi;
|
||||
return(mi);
|
||||
case CTL_WIPE:
|
||||
mc->searchstr[0] = '\0';
|
||||
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) &&
|
||||
(strncmp(mc->searchstr, mi->text,
|
||||
strlen(mi->text))) == 0)
|
||||
return menu_complete_path(mc);
|
||||
return(menu_complete_path(mc));
|
||||
|
||||
/*
|
||||
* 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->dummy = 1;
|
||||
mi->abort = 1;
|
||||
return mi;
|
||||
return(mi);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -327,7 +327,7 @@ menu_handle_key(XEvent *e, struct menu_ctx *mc, struct menu_q *menuq,
|
||||
mc->listing = 0;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -355,7 +355,7 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq)
|
||||
XftTextExtentsUtf8(X_Dpy, sc->xftfont,
|
||||
(const FcChar8*)mc->dispstr, strlen(mc->dispstr), &extents);
|
||||
mc->geom.w = extents.xOff;
|
||||
mc->geom.h = sc->xftfont->ascent + sc->xftfont->descent;
|
||||
mc->geom.h = sc->xftfont->height + 1;
|
||||
mc->num = 1;
|
||||
|
||||
TAILQ_FOREACH(mi, resultq, resultentry) {
|
||||
@ -364,11 +364,11 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq)
|
||||
(const FcChar8*)mi->print,
|
||||
MIN(strlen(mi->print), MENU_MAXENTRY), &extents);
|
||||
mc->geom.w = MAX(mc->geom.w, extents.xOff);
|
||||
mc->geom.h += sc->xftfont->ascent + sc->xftfont->descent;
|
||||
mc->geom.h += sc->xftfont->height + 1;
|
||||
mc->num++;
|
||||
}
|
||||
|
||||
area = screen_area(sc, mc->geom.x, mc->geom.y, 1);
|
||||
area = screen_area(sc, mc->geom.x, mc->geom.y, CWM_GAP);
|
||||
area.w += area.x - 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)
|
||||
xu_ptr_set(sc->rootwin, mc->geom.x, mc->geom.y);
|
||||
xu_ptr_setpos(sc->rootwin, mc->geom.x, mc->geom.y);
|
||||
|
||||
XClearWindow(X_Dpy, mc->win);
|
||||
XMoveResizeWindow(X_Dpy, mc->win, mc->geom.x, mc->geom.y,
|
||||
@ -403,15 +403,15 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq)
|
||||
(const FcChar8*)mc->dispstr, strlen(mc->dispstr));
|
||||
|
||||
TAILQ_FOREACH(mi, resultq, resultentry) {
|
||||
int y = n * (sc->xftfont->ascent + sc->xftfont->descent);
|
||||
int y = n * (sc->xftfont->height + 1) + sc->xftfont->ascent + 1;
|
||||
|
||||
/* Stop drawing when menu doesn't fit inside the screen. */
|
||||
if (mc->geom.y + y >= area.h)
|
||||
if (mc->geom.y + y > area.h)
|
||||
break;
|
||||
|
||||
XftDrawStringUtf8(mc->xftdraw,
|
||||
&sc->xftcolor[CWM_COLOR_MENU_FONT], sc->xftfont,
|
||||
0, y + sc->xftfont->ascent,
|
||||
0, y,
|
||||
(const FcChar8*)mi->print, strlen(mi->print));
|
||||
n++;
|
||||
}
|
||||
@ -425,7 +425,7 @@ menu_draw_entry(struct menu_ctx *mc, struct menu_q *resultq,
|
||||
{
|
||||
struct screen_ctx *sc = mc->sc;
|
||||
struct menu *mi;
|
||||
int color, i = 1, y;
|
||||
int color, i = 1;
|
||||
|
||||
TAILQ_FOREACH(mi, resultq, resultentry)
|
||||
if (entry == i++)
|
||||
@ -433,13 +433,14 @@ menu_draw_entry(struct menu_ctx *mc, struct menu_q *resultq,
|
||||
if (mi == NULL)
|
||||
return;
|
||||
|
||||
y = entry * (sc->xftfont->ascent + sc->xftfont->descent);
|
||||
color = (active) ? CWM_COLOR_MENU_FG : CWM_COLOR_MENU_BG;
|
||||
XftDrawRect(mc->xftdraw, &sc->xftcolor[color], 0, y,
|
||||
mc->geom.w, sc->xftfont->ascent + sc->xftfont->descent);
|
||||
XftDrawRect(mc->xftdraw, &sc->xftcolor[color], 0,
|
||||
(sc->xftfont->height + 1) * entry, mc->geom.w,
|
||||
(sc->xftfont->height + 1) + sc->xftfont->descent);
|
||||
color = (active) ? CWM_COLOR_MENU_FONT_SEL : CWM_COLOR_MENU_FONT;
|
||||
XftDrawStringUtf8(mc->xftdraw,
|
||||
&sc->xftcolor[color], sc->xftfont, 0, y + sc->xftfont->ascent,
|
||||
&sc->xftcolor[color], sc->xftfont,
|
||||
0, (sc->xftfont->height + 1) * entry + sc->xftfont->ascent + 1,
|
||||
(const FcChar8*)mi->print, strlen(mi->print));
|
||||
}
|
||||
|
||||
@ -477,7 +478,7 @@ menu_handle_release(struct menu_ctx *mc, struct menu_q *resultq, int x, int y)
|
||||
mi->text[0] = '\0';
|
||||
mi->dummy = 1;
|
||||
}
|
||||
return mi;
|
||||
return(mi);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -486,18 +487,18 @@ menu_calc_entry(struct menu_ctx *mc, int x, int y)
|
||||
struct screen_ctx *sc = mc->sc;
|
||||
int entry;
|
||||
|
||||
entry = y / (sc->xftfont->ascent + sc->xftfont->descent);
|
||||
entry = y / (sc->xftfont->height + 1);
|
||||
|
||||
/* in bounds? */
|
||||
if (x < 0 || x > mc->geom.w || y < 0 ||
|
||||
y > (sc->xftfont->ascent + sc->xftfont->descent) * mc->num ||
|
||||
y > (sc->xftfont->height + 1) * mc->num ||
|
||||
entry < 0 || entry >= mc->num)
|
||||
entry = -1;
|
||||
|
||||
if (entry == 0)
|
||||
entry = -1;
|
||||
|
||||
return entry;
|
||||
return(entry);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -580,12 +581,12 @@ menu_keycode(XKeyEvent *ev, enum ctltype *ctl, char *chr)
|
||||
}
|
||||
|
||||
if (*ctl != CTL_NONE)
|
||||
return 0;
|
||||
return(0);
|
||||
|
||||
if (XLookupString(ev, chr, 32, &ks, NULL) < 0)
|
||||
return -1;
|
||||
return(-1);
|
||||
|
||||
return 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
void
|
||||
|
61
parse.y
61
parse.y
@ -22,7 +22,7 @@
|
||||
%{
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "queue.h"
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
@ -73,7 +73,7 @@ typedef struct {
|
||||
%token BINDKEY UNBINDKEY BINDMOUSE UNBINDMOUSE
|
||||
%token FONTNAME STICKY GAP
|
||||
%token AUTOGROUP COMMAND IGNORE WM
|
||||
%token YES NO BORDERWIDTH MOVEAMOUNT HTILE VTILE
|
||||
%token YES NO BORDERWIDTH MOVEAMOUNT
|
||||
%token COLOR SNAPDIST
|
||||
%token ACTIVEBORDER INACTIVEBORDER URGENCYBORDER
|
||||
%token GROUPBORDER UNGROUPBORDER
|
||||
@ -83,7 +83,7 @@ typedef struct {
|
||||
%token <v.string> STRING
|
||||
%token <v.number> NUMBER
|
||||
%type <v.number> yesno
|
||||
%type <v.string> string numberstring
|
||||
%type <v.string> string
|
||||
%%
|
||||
|
||||
grammar : /* empty */
|
||||
@ -106,17 +106,6 @@ string : string STRING {
|
||||
| STRING
|
||||
;
|
||||
|
||||
numberstring : NUMBER {
|
||||
char *s;
|
||||
if (asprintf(&s, "%lld", $1) == -1) {
|
||||
yyerror("string: asprintf");
|
||||
YYERROR;
|
||||
}
|
||||
$$ = s;
|
||||
}
|
||||
| STRING
|
||||
;
|
||||
|
||||
yesno : YES { $$ = 1; }
|
||||
| NO { $$ = 0; }
|
||||
;
|
||||
@ -135,20 +124,6 @@ main : FONTNAME STRING {
|
||||
}
|
||||
conf->bwidth = $2;
|
||||
}
|
||||
| HTILE NUMBER {
|
||||
if ($2 < 0 || $2 > 99) {
|
||||
yyerror("invalid htile percent");
|
||||
YYERROR;
|
||||
}
|
||||
conf->htile = $2;
|
||||
}
|
||||
| VTILE NUMBER {
|
||||
if ($2 < 0 || $2 > 99) {
|
||||
yyerror("invalid vtile percent");
|
||||
YYERROR;
|
||||
}
|
||||
conf->vtile = $2;
|
||||
}
|
||||
| MOVEAMOUNT NUMBER {
|
||||
if ($2 < 0 || $2 > INT_MAX) {
|
||||
yyerror("invalid movemount");
|
||||
@ -222,7 +197,7 @@ main : FONTNAME STRING {
|
||||
conf->gap.left = $4;
|
||||
conf->gap.right = $5;
|
||||
}
|
||||
| BINDKEY numberstring string {
|
||||
| BINDKEY STRING string {
|
||||
if (!conf_bind_key(conf, $2, $3)) {
|
||||
yyerror("invalid bind-key: %s %s", $2, $3);
|
||||
free($2);
|
||||
@ -232,7 +207,7 @@ main : FONTNAME STRING {
|
||||
free($2);
|
||||
free($3);
|
||||
}
|
||||
| UNBINDKEY numberstring {
|
||||
| UNBINDKEY STRING {
|
||||
if (!conf_bind_key(conf, $2, NULL)) {
|
||||
yyerror("invalid unbind-key: %s", $2);
|
||||
free($2);
|
||||
@ -240,7 +215,7 @@ main : FONTNAME STRING {
|
||||
}
|
||||
free($2);
|
||||
}
|
||||
| BINDMOUSE numberstring string {
|
||||
| BINDMOUSE STRING string {
|
||||
if (!conf_bind_mouse(conf, $2, $3)) {
|
||||
yyerror("invalid bind-mouse: %s %s", $2, $3);
|
||||
free($2);
|
||||
@ -250,7 +225,7 @@ main : FONTNAME STRING {
|
||||
free($2);
|
||||
free($3);
|
||||
}
|
||||
| UNBINDMOUSE numberstring {
|
||||
| UNBINDMOUSE STRING {
|
||||
if (!conf_bind_mouse(conf, $2, NULL)) {
|
||||
yyerror("invalid unbind-mouse: %s", $2);
|
||||
free($2);
|
||||
@ -343,7 +318,6 @@ lookup(char *s)
|
||||
{ "fontname", FONTNAME},
|
||||
{ "gap", GAP},
|
||||
{ "groupborder", GROUPBORDER},
|
||||
{ "htile", HTILE},
|
||||
{ "ignore", IGNORE},
|
||||
{ "inactiveborder", INACTIVEBORDER},
|
||||
{ "menubg", MENUBG},
|
||||
@ -357,7 +331,6 @@ lookup(char *s)
|
||||
{ "unbind-mouse", UNBINDMOUSE},
|
||||
{ "ungroupborder", UNGROUPBORDER},
|
||||
{ "urgencyborder", URGENCYBORDER},
|
||||
{ "vtile", VTILE},
|
||||
{ "wm", WM},
|
||||
{ "yes", YES}
|
||||
};
|
||||
@ -387,7 +360,7 @@ lgetc(int quotec)
|
||||
if (parsebuf) {
|
||||
/* Read character from the parsebuffer instead of input. */
|
||||
if (parseindex >= 0) {
|
||||
c = (unsigned char)parsebuf[parseindex++];
|
||||
c = parsebuf[parseindex++];
|
||||
if (c != '\0')
|
||||
return (c);
|
||||
parsebuf = NULL;
|
||||
@ -396,7 +369,7 @@ lgetc(int quotec)
|
||||
}
|
||||
|
||||
if (pushback_index)
|
||||
return ((unsigned char)pushback_buffer[--pushback_index]);
|
||||
return (pushback_buffer[--pushback_index]);
|
||||
|
||||
if (quotec) {
|
||||
if ((c = getc(file->stream)) == EOF) {
|
||||
@ -437,10 +410,10 @@ lungetc(int c)
|
||||
if (parseindex >= 0)
|
||||
return (c);
|
||||
}
|
||||
if (pushback_index + 1 >= MAXPUSHBACK)
|
||||
if (pushback_index < MAXPUSHBACK-1)
|
||||
return (pushback_buffer[pushback_index++] = c);
|
||||
else
|
||||
return (EOF);
|
||||
pushback_buffer[pushback_index++] = c;
|
||||
return (c);
|
||||
}
|
||||
|
||||
int
|
||||
@ -453,7 +426,7 @@ findeol(void)
|
||||
/* skip to either EOF or the first real EOL */
|
||||
while (1) {
|
||||
if (pushback_index)
|
||||
c = (unsigned char)pushback_buffer[--pushback_index];
|
||||
c = pushback_buffer[--pushback_index];
|
||||
else
|
||||
c = lgetc(0);
|
||||
if (c == '\n') {
|
||||
@ -527,7 +500,7 @@ yylex(void)
|
||||
if (c == '-' || isdigit(c)) {
|
||||
do {
|
||||
*p++ = c;
|
||||
if ((size_t)(p-buf) >= sizeof(buf)) {
|
||||
if ((unsigned)(p-buf) >= sizeof(buf)) {
|
||||
yyerror("string too long");
|
||||
return (findeol());
|
||||
}
|
||||
@ -550,8 +523,8 @@ yylex(void)
|
||||
} else {
|
||||
nodigits:
|
||||
while (p > buf + 1)
|
||||
lungetc((unsigned char)*--p);
|
||||
c = (unsigned char)*--p;
|
||||
lungetc(*--p);
|
||||
c = *--p;
|
||||
if (c == '-')
|
||||
return (c);
|
||||
}
|
||||
@ -566,7 +539,7 @@ nodigits:
|
||||
if (isalnum(c) || c == ':' || c == '_' || c == '*' || c == '/') {
|
||||
do {
|
||||
*p++ = c;
|
||||
if ((size_t)(p-buf) >= sizeof(buf)) {
|
||||
if ((unsigned)(p-buf) >= sizeof(buf)) {
|
||||
yyerror("string too long");
|
||||
return (findeol());
|
||||
}
|
||||
|
70
screen.c
70
screen.c
@ -33,13 +33,14 @@
|
||||
#include "calmwm.h"
|
||||
|
||||
static struct geom screen_apply_gap(struct screen_ctx *, struct geom);
|
||||
static void screen_scan(struct screen_ctx *);
|
||||
|
||||
void
|
||||
screen_init(int which)
|
||||
{
|
||||
struct screen_ctx *sc;
|
||||
XSetWindowAttributes attr;
|
||||
Window *wins, w0, w1, active = None;
|
||||
XSetWindowAttributes rootattr;
|
||||
unsigned int nwins, w;
|
||||
|
||||
sc = xmalloc(sizeof(*sc));
|
||||
|
||||
@ -60,53 +61,39 @@ screen_init(int which)
|
||||
xu_ewmh_net_supported_wm_check(sc);
|
||||
|
||||
conf_group(sc);
|
||||
sc->group_last = sc->group_active;
|
||||
screen_update_geometry(sc);
|
||||
|
||||
xu_ewmh_net_desktop_names(sc);
|
||||
xu_ewmh_net_number_of_desktops(sc);
|
||||
xu_ewmh_net_showing_desktop(sc);
|
||||
xu_ewmh_net_virtual_roots(sc);
|
||||
active = xu_ewmh_get_net_active_window(sc);
|
||||
|
||||
attr.cursor = Conf.cursor[CF_NORMAL];
|
||||
attr.event_mask = SubstructureRedirectMask | SubstructureNotifyMask |
|
||||
EnterWindowMask | PropertyChangeMask | ButtonPressMask;
|
||||
XChangeWindowAttributes(X_Dpy, sc->rootwin, (CWEventMask | CWCursor), &attr);
|
||||
rootattr.cursor = Conf.cursor[CF_NORMAL];
|
||||
rootattr.event_mask = SubstructureRedirectMask |
|
||||
SubstructureNotifyMask | PropertyChangeMask | EnterWindowMask |
|
||||
LeaveWindowMask | ColormapChangeMask | BUTTONMASK;
|
||||
|
||||
XChangeWindowAttributes(X_Dpy, sc->rootwin,
|
||||
(CWEventMask | CWCursor), &rootattr);
|
||||
|
||||
/* Deal with existing clients. */
|
||||
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);
|
||||
|
||||
if (Conf.xrandr)
|
||||
XRRSelectInput(X_Dpy, sc->rootwin, RRScreenChangeNotifyMask);
|
||||
|
||||
screen_scan(sc);
|
||||
screen_updatestackingorder(sc);
|
||||
|
||||
TAILQ_INSERT_TAIL(&Screenq, sc, entry);
|
||||
|
||||
XSync(X_Dpy, False);
|
||||
}
|
||||
|
||||
static void
|
||||
screen_scan(struct screen_ctx *sc)
|
||||
{
|
||||
struct client_ctx *cc, *active = NULL;
|
||||
Window *wins, w0, w1, rwin, cwin;
|
||||
unsigned int nwins, i, mask;
|
||||
int rx, ry, wx, wy;
|
||||
|
||||
XQueryPointer(X_Dpy, sc->rootwin, &rwin, &cwin,
|
||||
&rx, &ry, &wx, &wy, &mask);
|
||||
|
||||
if (XQueryTree(X_Dpy, sc->rootwin, &w0, &w1, &wins, &nwins)) {
|
||||
for (i = 0; i < nwins; i++) {
|
||||
if ((cc = client_init(wins[i], sc)) != NULL)
|
||||
if (cc->win == cwin)
|
||||
active = cc;
|
||||
}
|
||||
XFree(wins);
|
||||
}
|
||||
if (active)
|
||||
client_set_active(active);
|
||||
}
|
||||
|
||||
struct screen_ctx *
|
||||
screen_find(Window win)
|
||||
{
|
||||
@ -114,10 +101,10 @@ screen_find(Window win)
|
||||
|
||||
TAILQ_FOREACH(sc, &Screenq, entry) {
|
||||
if (sc->rootwin == win)
|
||||
return sc;
|
||||
return(sc);
|
||||
}
|
||||
warnx("%s: failure win 0x%lx", __func__, win);
|
||||
return NULL;
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
@ -151,11 +138,11 @@ region_find(struct screen_ctx *sc, int x, int y)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
return(rc);
|
||||
}
|
||||
|
||||
struct geom
|
||||
screen_area(struct screen_ctx *sc, int x, int y, int apply_gap)
|
||||
screen_area(struct screen_ctx *sc, int x, int y, enum apply_gap apply_gap)
|
||||
{
|
||||
struct region_ctx *rc;
|
||||
struct geom area = sc->view;
|
||||
@ -169,7 +156,7 @@ screen_area(struct screen_ctx *sc, int x, int y, int apply_gap)
|
||||
}
|
||||
if (apply_gap)
|
||||
area = screen_apply_gap(sc, area);
|
||||
return area;
|
||||
return(area);
|
||||
}
|
||||
|
||||
void
|
||||
@ -239,7 +226,7 @@ screen_apply_gap(struct screen_ctx *sc, struct geom geom)
|
||||
geom.w -= (sc->gap.left + sc->gap.right);
|
||||
geom.h -= (sc->gap.top + sc->gap.bottom);
|
||||
|
||||
return geom;
|
||||
return(geom);
|
||||
}
|
||||
|
||||
/* Bring back clients which are beyond the screen. */
|
||||
@ -288,12 +275,15 @@ void
|
||||
screen_prop_win_draw(struct screen_ctx *sc, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int i;
|
||||
char *text;
|
||||
XGlyphInfo extents;
|
||||
|
||||
va_start(ap, fmt);
|
||||
xvasprintf(&text, fmt, ap);
|
||||
i = vasprintf(&text, fmt, ap);
|
||||
va_end(ap);
|
||||
if (i < 0 || text == NULL)
|
||||
err(1, "vasprintf");
|
||||
|
||||
XftTextExtentsUtf8(X_Dpy, sc->xftfont, (const FcChar8*)text,
|
||||
strlen(text), &extents);
|
||||
|
10
search.c
10
search.c
@ -46,13 +46,13 @@ match_substr(char *sub, char *str, int zeroidx)
|
||||
unsigned int n, flen;
|
||||
|
||||
if (sub == NULL || str == NULL)
|
||||
return 0;
|
||||
return(0);
|
||||
|
||||
len = strlen(str);
|
||||
sublen = strlen(sub);
|
||||
|
||||
if (sublen > len)
|
||||
return 0;
|
||||
return(0);
|
||||
|
||||
if (zeroidx)
|
||||
flen = 0;
|
||||
@ -61,9 +61,9 @@ match_substr(char *sub, char *str, int zeroidx)
|
||||
|
||||
for (n = 0; n <= flen; n++)
|
||||
if (strncasecmp(sub, str + n, sublen) == 0)
|
||||
return 1;
|
||||
return(1);
|
||||
|
||||
return 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
void
|
||||
@ -94,7 +94,7 @@ search_match_client(struct menu_q *menuq, struct menu_q *resultq, char *search)
|
||||
}
|
||||
|
||||
/* Match on window resource class. */
|
||||
if ((tier < 0) && match_substr(search, cc->res_class, 0))
|
||||
if ((tier < 0) && match_substr(search, cc->ch.res_class, 0))
|
||||
tier = 2;
|
||||
|
||||
if (tier < 0)
|
||||
|
8
util.c
8
util.c
@ -53,7 +53,7 @@ u_exec(char *argstr)
|
||||
{
|
||||
#define MAXARGLEN 20
|
||||
char *args[MAXARGLEN], **ap = args;
|
||||
char **end = &args[MAXARGLEN - 2], *tmp;
|
||||
char **end = &args[MAXARGLEN - 1], *tmp;
|
||||
char *s = argstr;
|
||||
|
||||
while (ap < end && (*ap = strsep(&argstr, " \t")) != NULL) {
|
||||
@ -92,12 +92,12 @@ u_argv(char * const *argv)
|
||||
char *p;
|
||||
|
||||
if (argv == 0)
|
||||
return NULL;
|
||||
return(NULL);
|
||||
|
||||
for (i = 0; argv[i]; i++)
|
||||
siz += strlen(argv[i]) + 1;
|
||||
if (siz == 0)
|
||||
return NULL;
|
||||
return(NULL);
|
||||
|
||||
p = xmalloc(siz);
|
||||
strlcpy(p, argv[0], siz);
|
||||
@ -105,7 +105,7 @@ u_argv(char * const *argv)
|
||||
strlcat(p, " ", siz);
|
||||
strlcat(p, argv[i], siz);
|
||||
}
|
||||
return p;
|
||||
return(p);
|
||||
}
|
||||
|
||||
static void
|
||||
|
22
xevents.c
22
xevents.c
@ -69,7 +69,7 @@ void (*xev_handlers[LASTEvent])(XEvent *) = {
|
||||
};
|
||||
|
||||
static KeySym modkeys[] = { XK_Alt_L, XK_Alt_R, XK_Super_L, XK_Super_R,
|
||||
XK_Control_L, XK_Control_R, XK_ISO_Level3_Shift };
|
||||
XK_Control_L, XK_Control_R };
|
||||
|
||||
static void
|
||||
xev_handle_maprequest(XEvent *ee)
|
||||
@ -84,13 +84,13 @@ xev_handle_maprequest(XEvent *ee)
|
||||
return;
|
||||
|
||||
if ((old_cc = client_current(sc)) != NULL)
|
||||
client_ptr_save(old_cc);
|
||||
client_ptrsave(old_cc);
|
||||
|
||||
if ((cc = client_find(e->window)) == NULL)
|
||||
cc = client_init(e->window, NULL);
|
||||
cc = client_init(e->window, NULL, 0);
|
||||
|
||||
if ((cc != NULL) && (!(cc->flags & CLIENT_IGNORE)))
|
||||
client_ptr_warp(cc);
|
||||
client_ptrwarp(cc);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -103,7 +103,7 @@ xev_handle_unmapnotify(XEvent *ee)
|
||||
|
||||
if ((cc = client_find(e->window)) != NULL) {
|
||||
if (e->send_event) {
|
||||
xu_set_wm_state(cc->win, WithdrawnState);
|
||||
client_set_wm_state(cc, WithdrawnState);
|
||||
} else {
|
||||
if (!(cc->flags & CLIENT_HIDDEN))
|
||||
client_remove(cc);
|
||||
@ -191,10 +191,10 @@ xev_handle_propertynotify(XEvent *ee)
|
||||
if ((cc = client_find(e->window)) != NULL) {
|
||||
switch (e->atom) {
|
||||
case XA_WM_NORMAL_HINTS:
|
||||
client_get_sizehints(cc);
|
||||
client_getsizehints(cc);
|
||||
break;
|
||||
case XA_WM_NAME:
|
||||
client_set_name(cc);
|
||||
client_setname(cc);
|
||||
break;
|
||||
case XA_WM_HINTS:
|
||||
client_wm_hints(cc);
|
||||
@ -208,7 +208,7 @@ xev_handle_propertynotify(XEvent *ee)
|
||||
break;
|
||||
default:
|
||||
if (e->atom == ewmh[_NET_WM_NAME])
|
||||
client_set_name(cc);
|
||||
client_setname(cc);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@ -230,7 +230,7 @@ xev_handle_enternotify(XEvent *ee)
|
||||
Last_Event_Time = e->time;
|
||||
|
||||
if ((cc = client_find(e->window)) != NULL)
|
||||
client_set_active(cc);
|
||||
client_setactive(cc);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -399,9 +399,9 @@ xev_handle_clientmessage(XEvent *ee)
|
||||
} else if (e->message_type == ewmh[_NET_ACTIVE_WINDOW]) {
|
||||
if ((cc = client_find(e->window)) != NULL) {
|
||||
if ((old_cc = client_current(NULL)) != NULL)
|
||||
client_ptr_save(old_cc);
|
||||
client_ptrsave(old_cc);
|
||||
client_show(cc);
|
||||
client_ptr_warp(cc);
|
||||
client_ptrwarp(cc);
|
||||
}
|
||||
} else if (e->message_type == ewmh[_NET_WM_DESKTOP]) {
|
||||
if ((cc = client_find(e->window)) != NULL) {
|
||||
|
27
xmalloc.c
27
xmalloc.c
@ -43,7 +43,7 @@ xmalloc(size_t siz)
|
||||
if ((p = malloc(siz)) == NULL)
|
||||
err(1, "malloc");
|
||||
|
||||
return p;
|
||||
return(p);
|
||||
}
|
||||
|
||||
void *
|
||||
@ -58,7 +58,7 @@ xcalloc(size_t no, size_t siz)
|
||||
if ((p = calloc(no, siz)) == NULL)
|
||||
err(1, "calloc");
|
||||
|
||||
return p;
|
||||
return(p);
|
||||
}
|
||||
|
||||
void *
|
||||
@ -70,7 +70,7 @@ xreallocarray(void *ptr, size_t nmemb, size_t size)
|
||||
if (p == NULL)
|
||||
errx(1, "xreallocarray: out of memory (new_size %zu bytes)",
|
||||
nmemb * size);
|
||||
return p;
|
||||
return(p);
|
||||
}
|
||||
|
||||
char *
|
||||
@ -81,7 +81,7 @@ xstrdup(const char *str)
|
||||
if ((p = strdup(str)) == NULL)
|
||||
err(1, "strdup");
|
||||
|
||||
return p;
|
||||
return(p);
|
||||
}
|
||||
|
||||
int
|
||||
@ -91,20 +91,11 @@ xasprintf(char **ret, const char *fmt, ...)
|
||||
int i;
|
||||
|
||||
va_start(ap, fmt);
|
||||
i = xvasprintf(ret, fmt, ap);
|
||||
i = vasprintf(ret, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int
|
||||
xvasprintf(char **ret, const char *fmt, va_list ap)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = vasprintf(ret, fmt, ap);
|
||||
if (i == -1)
|
||||
err(1, "vasprintf");
|
||||
|
||||
return i;
|
||||
if (i < 0 || *ret == NULL)
|
||||
err(1, "asprintf");
|
||||
|
||||
return(i);
|
||||
}
|
||||
|
172
xutil.c
172
xutil.c
@ -32,7 +32,7 @@
|
||||
#include "calmwm.h"
|
||||
|
||||
void
|
||||
xu_ptr_get(Window win, int *x, int *y)
|
||||
xu_ptr_getpos(Window win, int *x, int *y)
|
||||
{
|
||||
Window w0, w1;
|
||||
int tmp0, tmp1;
|
||||
@ -42,13 +42,13 @@ xu_ptr_get(Window win, int *x, int *y)
|
||||
}
|
||||
|
||||
void
|
||||
xu_ptr_set(Window win, int x, int y)
|
||||
xu_ptr_setpos(Window win, int x, int y)
|
||||
{
|
||||
XWarpPointer(X_Dpy, None, win, 0, 0, 0, 0, x, y);
|
||||
}
|
||||
|
||||
int
|
||||
xu_get_prop(Window win, Atom atm, Atom type, long len, unsigned char **p)
|
||||
xu_getprop(Window win, Atom atm, Atom type, long len, unsigned char **p)
|
||||
{
|
||||
Atom realtype;
|
||||
unsigned long n, extra;
|
||||
@ -56,16 +56,16 @@ xu_get_prop(Window win, Atom atm, Atom type, long len, unsigned char **p)
|
||||
|
||||
if (XGetWindowProperty(X_Dpy, win, atm, 0L, len, False, type,
|
||||
&realtype, &format, &n, &extra, p) != Success || *p == NULL)
|
||||
return -1;
|
||||
return(-1);
|
||||
|
||||
if (n == 0)
|
||||
XFree(*p);
|
||||
|
||||
return n;
|
||||
return(n);
|
||||
}
|
||||
|
||||
int
|
||||
xu_get_strprop(Window win, Atom atm, char **text) {
|
||||
xu_getstrprop(Window win, Atom atm, char **text) {
|
||||
XTextProperty prop;
|
||||
char **list;
|
||||
int nitems = 0;
|
||||
@ -73,10 +73,8 @@ xu_get_strprop(Window win, Atom atm, char **text) {
|
||||
*text = NULL;
|
||||
|
||||
XGetTextProperty(X_Dpy, win, &prop, atm);
|
||||
if (!prop.nitems) {
|
||||
XFree(prop.value);
|
||||
return 0;
|
||||
}
|
||||
if (!prop.nitems)
|
||||
return(0);
|
||||
|
||||
if (Xutf8TextPropertyToTextList(X_Dpy, &prop, &list,
|
||||
&nitems) == Success && nitems > 0 && *list) {
|
||||
@ -92,101 +90,10 @@ xu_get_strprop(Window win, Atom atm, char **text) {
|
||||
}
|
||||
XFreeStringList(list);
|
||||
}
|
||||
|
||||
XFree(prop.value);
|
||||
|
||||
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);
|
||||
return(nitems);
|
||||
}
|
||||
|
||||
/* Root Window Properties */
|
||||
@ -298,6 +205,22 @@ xu_ewmh_net_active_window(struct screen_ctx *sc, Window w)
|
||||
XA_WINDOW, 32, PropModeReplace, (unsigned char *)&w, 1);
|
||||
}
|
||||
|
||||
Window
|
||||
xu_ewmh_get_net_active_window(struct screen_ctx *sc)
|
||||
{
|
||||
long *p;
|
||||
Window win;
|
||||
|
||||
if ((xu_getprop(sc->rootwin, ewmh[_NET_ACTIVE_WINDOW],
|
||||
XA_WINDOW, 32, (unsigned char **)&p)) <= 0)
|
||||
return(None);
|
||||
|
||||
win = (Window)*p;
|
||||
XFree(p);
|
||||
|
||||
return(win);
|
||||
}
|
||||
|
||||
void
|
||||
xu_ewmh_net_number_of_desktops(struct screen_ctx *sc)
|
||||
{
|
||||
@ -347,7 +270,7 @@ xu_ewmh_net_desktop_names(struct screen_ctx *sc)
|
||||
|
||||
/* Let group names be overwritten if _NET_DESKTOP_NAMES is set. */
|
||||
|
||||
if ((j = xu_get_prop(sc->rootwin, ewmh[_NET_DESKTOP_NAMES],
|
||||
if ((j = xu_getprop(sc->rootwin, ewmh[_NET_DESKTOP_NAMES],
|
||||
cwmh[UTF8_STRING], 0xffffff, (unsigned char **)&prop_ret)) > 0) {
|
||||
prop_ret[j - 1] = '\0'; /* paranoia */
|
||||
while (i < j) {
|
||||
@ -389,21 +312,8 @@ xu_ewmh_net_desktop_names(struct screen_ctx *sc)
|
||||
}
|
||||
|
||||
/* 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
|
||||
xu_ewmh_set_net_wm_desktop(struct client_ctx *cc)
|
||||
xu_ewmh_net_wm_desktop(struct client_ctx *cc)
|
||||
{
|
||||
long num = 0xffffffff;
|
||||
|
||||
@ -419,15 +329,15 @@ xu_ewmh_get_net_wm_state(struct client_ctx *cc, int *n)
|
||||
{
|
||||
Atom *state, *p = NULL;
|
||||
|
||||
if ((*n = xu_get_prop(cc->win, ewmh[_NET_WM_STATE], XA_ATOM, 64L,
|
||||
if ((*n = xu_getprop(cc->win, ewmh[_NET_WM_STATE], XA_ATOM, 64L,
|
||||
(unsigned char **)&p)) <= 0)
|
||||
return NULL;
|
||||
return(NULL);
|
||||
|
||||
state = xreallocarray(NULL, *n, sizeof(Atom));
|
||||
(void)memcpy(state, p, *n * sizeof(Atom));
|
||||
XFree((char *)p);
|
||||
|
||||
return state;
|
||||
return(state);
|
||||
}
|
||||
|
||||
void
|
||||
@ -435,9 +345,9 @@ xu_ewmh_handle_net_wm_state_msg(struct client_ctx *cc, int action,
|
||||
Atom first, Atom second)
|
||||
{
|
||||
unsigned int i;
|
||||
struct handlers {
|
||||
Atom atom;
|
||||
int flag;
|
||||
static struct handlers {
|
||||
int atom;
|
||||
int property;
|
||||
void (*toggle)(struct client_ctx *);
|
||||
} handlers[] = {
|
||||
{ _NET_WM_STATE_STICKY,
|
||||
@ -475,11 +385,11 @@ xu_ewmh_handle_net_wm_state_msg(struct client_ctx *cc, int action,
|
||||
continue;
|
||||
switch (action) {
|
||||
case _NET_WM_STATE_ADD:
|
||||
if (!(cc->flags & handlers[i].flag))
|
||||
if (!(cc->flags & handlers[i].property))
|
||||
handlers[i].toggle(cc);
|
||||
break;
|
||||
case _NET_WM_STATE_REMOVE:
|
||||
if (cc->flags & handlers[i].flag)
|
||||
if (cc->flags & handlers[i].property)
|
||||
handlers[i].toggle(cc);
|
||||
break;
|
||||
case _NET_WM_STATE_TOGGLE:
|
||||
@ -566,3 +476,13 @@ xu_ewmh_set_net_wm_state(struct client_ctx *cc)
|
||||
XDeleteProperty(X_Dpy, cc->win, ewmh[_NET_WM_STATE]);
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user