mirror of
https://github.com/leahneukirchen/cwm.git
synced 2023-08-10 21:13:12 +03:00
cvsimport
* refs/heads/master: (23 commits) Check the atom type on propertynotify before iterating. use screen_find() for xrandr crtc changes Find the managed screen from the parent window for client_current(). Print window id in hex; while here, remove unnecessary newline. Similar to keypress event, fetch the screen from the event root window in the buttonpress handler; bail if we don't manage the screen. Allows us to find the current client based on the screen/event root. extend verbose logging for key/button events [keypress event] turns out we've been checking the wrong window for a matching client thus always falling back to client_current(); while the current client is problaby right in most cases, use event's subwindow (not window) to find the client. Bail early if this event came to us from a screen we don't manage. This is result of us grabing all keybindings off the root window instead of selectively. add parans for readibility Teach client_current() to use a screen to find the current client instead of iterating over all (fallback if no screen provided for now). Initially convert trivial uses of client_current(). check cc->gc directly zip extra lines gc clientq inside groups, instead use the better maintained one per-screen shuffle deck chairs: rename group actions to match intent for clarity same thing as screen_find() Separate out the menu window from the client resize/move geom window; in each case, create and destroy on-demand. Isolate more menu specific code. fix a few misplaced (and misnamed) ewmh root window functions _NET_WORKAREA needs ngroups, so screen_update_geometry() needs to come after conf_group(). simplify xftcolor config Tie group number and name together during config. Move the group index (desktop number) check to the only 2 callers that require checking due to ewmh. ...
This commit is contained in:
commit
85d88f3304
18
calmwm.c
18
calmwm.c
@ -55,7 +55,7 @@ main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
char *display_name = NULL;
|
char *display_name = NULL;
|
||||||
char *fallback;
|
char *fallback;
|
||||||
int ch, xfd;
|
int ch, xfd, nflag = 0;
|
||||||
struct pollfd pfd[1];
|
struct pollfd pfd[1];
|
||||||
|
|
||||||
if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
|
if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
|
||||||
@ -66,7 +66,7 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
fallback = u_argv(argv);
|
fallback = u_argv(argv);
|
||||||
Conf.wm_argv = u_argv(argv);
|
Conf.wm_argv = u_argv(argv);
|
||||||
while ((ch = getopt(argc, argv, "c:d:v")) != -1) {
|
while ((ch = getopt(argc, argv, "c:d:nv")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'c':
|
case 'c':
|
||||||
free(Conf.conf_file);
|
free(Conf.conf_file);
|
||||||
@ -75,6 +75,9 @@ main(int argc, char **argv)
|
|||||||
case 'd':
|
case 'd':
|
||||||
display_name = optarg;
|
display_name = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'n':
|
||||||
|
nflag = 1;
|
||||||
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
Conf.debug++;
|
Conf.debug++;
|
||||||
break;
|
break;
|
||||||
@ -90,8 +93,13 @@ main(int argc, char **argv)
|
|||||||
if (signal(SIGHUP, sighdlr) == SIG_ERR)
|
if (signal(SIGHUP, sighdlr) == SIG_ERR)
|
||||||
err(1, "signal");
|
err(1, "signal");
|
||||||
|
|
||||||
if (parse_config(Conf.conf_file, &Conf) == -1)
|
if (parse_config(Conf.conf_file, &Conf) == -1) {
|
||||||
warnx("error parsing config file");
|
warnx("error parsing config file");
|
||||||
|
if (nflag)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (nflag)
|
||||||
|
return 0;
|
||||||
|
|
||||||
xfd = x_init(display_name);
|
xfd = x_init(display_name);
|
||||||
cwm_status = CWM_RUNNING;
|
cwm_status = CWM_RUNNING;
|
||||||
@ -159,8 +167,6 @@ x_teardown(void)
|
|||||||
DefaultColormap(X_Dpy, sc->which),
|
DefaultColormap(X_Dpy, sc->which),
|
||||||
&sc->xftcolor[i]);
|
&sc->xftcolor[i]);
|
||||||
XftFontClose(X_Dpy, sc->xftfont);
|
XftFontClose(X_Dpy, sc->xftfont);
|
||||||
XftDrawDestroy(sc->menu.xftdraw);
|
|
||||||
XDestroyWindow(X_Dpy, sc->menu.win);
|
|
||||||
XUngrabKey(X_Dpy, AnyKey, AnyModifier, sc->rootwin);
|
XUngrabKey(X_Dpy, AnyKey, AnyModifier, sc->rootwin);
|
||||||
}
|
}
|
||||||
XUngrabPointer(X_Dpy, CurrentTime);
|
XUngrabPointer(X_Dpy, CurrentTime);
|
||||||
@ -221,7 +227,7 @@ usage(void)
|
|||||||
{
|
{
|
||||||
extern char *__progname;
|
extern char *__progname;
|
||||||
|
|
||||||
(void)fprintf(stderr, "usage: %s [-v] [-c file] [-d display]\n",
|
(void)fprintf(stderr, "usage: %s [-nv] [-c file] [-d display]\n",
|
||||||
__progname);
|
__progname);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
33
calmwm.h
33
calmwm.h
@ -68,9 +68,6 @@ size_t strlcpy(char *, const char *, size_t);
|
|||||||
|
|
||||||
#define BUTTONMASK (ButtonPressMask | ButtonReleaseMask)
|
#define BUTTONMASK (ButtonPressMask | ButtonReleaseMask)
|
||||||
#define MOUSEMASK (BUTTONMASK | PointerMotionMask)
|
#define MOUSEMASK (BUTTONMASK | PointerMotionMask)
|
||||||
#define MENUMASK (MOUSEMASK | ButtonMotionMask | KeyPressMask | \
|
|
||||||
ExposureMask)
|
|
||||||
#define MENUGRABMASK (MOUSEMASK | ButtonMotionMask | StructureNotifyMask)
|
|
||||||
#define IGNOREMODMASK (LockMask | Mod2Mask | 0x2000)
|
#define IGNOREMODMASK (LockMask | Mod2Mask | 0x2000)
|
||||||
|
|
||||||
/* direction/amount */
|
/* direction/amount */
|
||||||
@ -145,7 +142,6 @@ TAILQ_HEAD(ignore_q, winname);
|
|||||||
|
|
||||||
struct client_ctx {
|
struct client_ctx {
|
||||||
TAILQ_ENTRY(client_ctx) entry;
|
TAILQ_ENTRY(client_ctx) entry;
|
||||||
TAILQ_ENTRY(client_ctx) group_entry;
|
|
||||||
struct screen_ctx *sc;
|
struct screen_ctx *sc;
|
||||||
struct group_ctx *gc;
|
struct group_ctx *gc;
|
||||||
Window win;
|
Window win;
|
||||||
@ -211,7 +207,6 @@ struct group_ctx {
|
|||||||
struct screen_ctx *sc;
|
struct screen_ctx *sc;
|
||||||
char *name;
|
char *name;
|
||||||
int num;
|
int num;
|
||||||
struct client_q clientq;
|
|
||||||
};
|
};
|
||||||
TAILQ_HEAD(group_q, group_ctx);
|
TAILQ_HEAD(group_q, group_ctx);
|
||||||
|
|
||||||
@ -250,7 +245,7 @@ struct screen_ctx {
|
|||||||
struct {
|
struct {
|
||||||
Window win;
|
Window win;
|
||||||
XftDraw *xftdraw;
|
XftDraw *xftdraw;
|
||||||
} menu;
|
} prop;
|
||||||
XftColor xftcolor[CWM_COLOR_NITEMS];
|
XftColor xftcolor[CWM_COLOR_NITEMS];
|
||||||
XftFont *xftfont;
|
XftFont *xftfont;
|
||||||
};
|
};
|
||||||
@ -420,7 +415,7 @@ void usage(void);
|
|||||||
|
|
||||||
void client_applysizehints(struct client_ctx *);
|
void client_applysizehints(struct client_ctx *);
|
||||||
void client_config(struct client_ctx *);
|
void client_config(struct client_ctx *);
|
||||||
struct client_ctx *client_current(void);
|
struct client_ctx *client_current(struct screen_ctx *);
|
||||||
void client_cycle(struct screen_ctx *, int);
|
void client_cycle(struct screen_ctx *, int);
|
||||||
void client_remove(struct client_ctx *);
|
void client_remove(struct client_ctx *);
|
||||||
void client_draw_border(struct client_ctx *);
|
void client_draw_border(struct client_ctx *);
|
||||||
@ -456,25 +451,24 @@ void client_toggle_skip_taskbar(struct client_ctx *);
|
|||||||
void client_toggle_sticky(struct client_ctx *);
|
void client_toggle_sticky(struct client_ctx *);
|
||||||
void client_toggle_vmaximize(struct client_ctx *);
|
void client_toggle_vmaximize(struct client_ctx *);
|
||||||
void client_transient(struct client_ctx *);
|
void client_transient(struct client_ctx *);
|
||||||
void client_unhide(struct client_ctx *);
|
|
||||||
void client_urgency(struct client_ctx *);
|
void client_urgency(struct client_ctx *);
|
||||||
void client_vtile(struct client_ctx *);
|
void client_vtile(struct client_ctx *);
|
||||||
void client_wm_hints(struct client_ctx *);
|
void client_wm_hints(struct client_ctx *);
|
||||||
|
|
||||||
void group_alltoggle(struct screen_ctx *);
|
|
||||||
void group_assign(struct group_ctx *, struct client_ctx *);
|
void group_assign(struct group_ctx *, struct client_ctx *);
|
||||||
int group_autogroup(struct client_ctx *);
|
int group_autogroup(struct client_ctx *);
|
||||||
void group_cycle(struct screen_ctx *, int);
|
void group_cycle(struct screen_ctx *, int);
|
||||||
void group_hide(struct group_ctx *);
|
void group_hide(struct group_ctx *);
|
||||||
void group_hidetoggle(struct screen_ctx *, int);
|
|
||||||
int group_holds_only_hidden(struct group_ctx *);
|
int group_holds_only_hidden(struct group_ctx *);
|
||||||
int group_holds_only_sticky(struct group_ctx *);
|
int group_holds_only_sticky(struct group_ctx *);
|
||||||
void group_init(struct screen_ctx *, int);
|
void group_init(struct screen_ctx *, int, const char *);
|
||||||
void group_movetogroup(struct client_ctx *, int);
|
void group_movetogroup(struct client_ctx *, int);
|
||||||
void group_only(struct screen_ctx *, int);
|
void group_only(struct screen_ctx *, int);
|
||||||
void group_close(struct screen_ctx *, int);
|
void group_close(struct screen_ctx *, int);
|
||||||
int group_restore(struct client_ctx *);
|
int group_restore(struct client_ctx *);
|
||||||
void group_show(struct group_ctx *);
|
void group_show(struct group_ctx *);
|
||||||
|
void group_toggle(struct screen_ctx *, int);
|
||||||
|
void group_toggle_all(struct screen_ctx *);
|
||||||
void group_toggle_membership(struct client_ctx *);
|
void group_toggle_membership(struct client_ctx *);
|
||||||
void group_update_names(struct screen_ctx *);
|
void group_update_names(struct screen_ctx *);
|
||||||
|
|
||||||
@ -506,6 +500,12 @@ void screen_init(int);
|
|||||||
void screen_update_geometry(struct screen_ctx *);
|
void screen_update_geometry(struct screen_ctx *);
|
||||||
void screen_updatestackingorder(struct screen_ctx *);
|
void screen_updatestackingorder(struct screen_ctx *);
|
||||||
void screen_assert_clients_within(struct screen_ctx *);
|
void screen_assert_clients_within(struct screen_ctx *);
|
||||||
|
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 kbfunc_cwm_status(void *, struct cargs *);
|
void kbfunc_cwm_status(void *, struct cargs *);
|
||||||
void kbfunc_ptrmove(void *, struct cargs *);
|
void kbfunc_ptrmove(void *, struct cargs *);
|
||||||
@ -532,7 +532,7 @@ void kbfunc_group_toggle(void *, struct cargs *);
|
|||||||
void kbfunc_group_only(void *, struct cargs *);
|
void kbfunc_group_only(void *, struct cargs *);
|
||||||
void kbfunc_group_close(void *, struct cargs *);
|
void kbfunc_group_close(void *, struct cargs *);
|
||||||
void kbfunc_group_cycle(void *, struct cargs *);
|
void kbfunc_group_cycle(void *, struct cargs *);
|
||||||
void kbfunc_group_alltoggle(void *, struct cargs *);
|
void kbfunc_group_toggle_all(void *, struct cargs *);
|
||||||
void kbfunc_menu_client(void *, struct cargs *);
|
void kbfunc_menu_client(void *, struct cargs *);
|
||||||
void kbfunc_menu_cmd(void *, struct cargs *);
|
void kbfunc_menu_cmd(void *, struct cargs *);
|
||||||
void kbfunc_menu_group(void *, struct cargs *);
|
void kbfunc_menu_group(void *, struct cargs *);
|
||||||
@ -544,10 +544,6 @@ void kbfunc_exec_cmd(void *, struct cargs *);
|
|||||||
void kbfunc_exec_lock(void *, struct cargs *);
|
void kbfunc_exec_lock(void *, struct cargs *);
|
||||||
void kbfunc_exec_term(void *, struct cargs *);
|
void kbfunc_exec_term(void *, struct cargs *);
|
||||||
|
|
||||||
void menu_windraw(struct screen_ctx *, Window,
|
|
||||||
const char *, ...)
|
|
||||||
__attribute__((__format__ (printf, 3, 4)))
|
|
||||||
__attribute__((__nonnull__ (3)));
|
|
||||||
struct menu *menu_filter(struct screen_ctx *, struct menu_q *,
|
struct menu *menu_filter(struct screen_ctx *, struct menu_q *,
|
||||||
const char *, const char *, int,
|
const char *, const char *, int,
|
||||||
void (*)(struct menu_q *, struct menu_q *, char *),
|
void (*)(struct menu_q *, struct menu_q *, char *),
|
||||||
@ -577,6 +573,7 @@ void conf_grab_mouse(Window);
|
|||||||
void conf_init(struct conf *);
|
void conf_init(struct conf *);
|
||||||
void conf_ignore(struct conf *, const char *);
|
void conf_ignore(struct conf *, const char *);
|
||||||
void conf_screen(struct screen_ctx *);
|
void conf_screen(struct screen_ctx *);
|
||||||
|
void conf_group(struct screen_ctx *);
|
||||||
|
|
||||||
void xev_process(void);
|
void xev_process(void);
|
||||||
|
|
||||||
@ -589,13 +586,13 @@ void xu_xorcolor(XftColor, XftColor, XftColor *);
|
|||||||
void xu_ewmh_net_supported(struct screen_ctx *);
|
void xu_ewmh_net_supported(struct screen_ctx *);
|
||||||
void xu_ewmh_net_supported_wm_check(struct screen_ctx *);
|
void xu_ewmh_net_supported_wm_check(struct screen_ctx *);
|
||||||
void xu_ewmh_net_desktop_geometry(struct screen_ctx *);
|
void xu_ewmh_net_desktop_geometry(struct screen_ctx *);
|
||||||
|
void xu_ewmh_net_desktop_viewport(struct screen_ctx *);
|
||||||
void xu_ewmh_net_workarea(struct screen_ctx *);
|
void xu_ewmh_net_workarea(struct screen_ctx *);
|
||||||
void xu_ewmh_net_client_list(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_client_list_stacking(struct screen_ctx *);
|
||||||
void xu_ewmh_net_active_window(struct screen_ctx *, Window);
|
void xu_ewmh_net_active_window(struct screen_ctx *, Window);
|
||||||
Window xu_ewmh_get_net_active_window(struct screen_ctx *);
|
Window xu_ewmh_get_net_active_window(struct screen_ctx *);
|
||||||
void xu_ewmh_net_wm_desktop_viewport(struct screen_ctx *);
|
void xu_ewmh_net_number_of_desktops(struct screen_ctx *);
|
||||||
void xu_ewmh_net_wm_number_of_desktops(struct screen_ctx *);
|
|
||||||
void xu_ewmh_net_showing_desktop(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_virtual_roots(struct screen_ctx *);
|
||||||
void xu_ewmh_net_current_desktop(struct screen_ctx *);
|
void xu_ewmh_net_current_desktop(struct screen_ctx *);
|
||||||
|
59
client.c
59
client.c
@ -128,7 +128,7 @@ client_init(Window win, struct screen_ctx *sc, int active)
|
|||||||
if (client_get_wm_state(cc) == IconicState)
|
if (client_get_wm_state(cc) == IconicState)
|
||||||
client_hide(cc);
|
client_hide(cc);
|
||||||
else
|
else
|
||||||
client_unhide(cc);
|
client_show(cc);
|
||||||
|
|
||||||
if (mapped) {
|
if (mapped) {
|
||||||
if (cc->gc) {
|
if (cc->gc) {
|
||||||
@ -183,9 +183,6 @@ client_remove(struct client_ctx *cc)
|
|||||||
if (cc->flags & CLIENT_ACTIVE)
|
if (cc->flags & CLIENT_ACTIVE)
|
||||||
xu_ewmh_net_active_window(sc, None);
|
xu_ewmh_net_active_window(sc, None);
|
||||||
|
|
||||||
if (cc->gc != NULL)
|
|
||||||
TAILQ_REMOVE(&cc->gc->clientq, cc, group_entry);
|
|
||||||
|
|
||||||
while ((wn = TAILQ_FIRST(&cc->nameq)) != NULL) {
|
while ((wn = TAILQ_FIRST(&cc->nameq)) != NULL) {
|
||||||
TAILQ_REMOVE(&cc->nameq, wn, entry);
|
TAILQ_REMOVE(&cc->nameq, wn, entry);
|
||||||
free(wn->name);
|
free(wn->name);
|
||||||
@ -221,7 +218,7 @@ client_setactive(struct client_ctx *cc)
|
|||||||
if (cc->flags & CLIENT_WM_TAKE_FOCUS)
|
if (cc->flags & CLIENT_WM_TAKE_FOCUS)
|
||||||
client_msg(cc, cwmh[WM_TAKE_FOCUS], Last_Event_Time);
|
client_msg(cc, cwmh[WM_TAKE_FOCUS], Last_Event_Time);
|
||||||
|
|
||||||
if ((oldcc = client_current()) != NULL) {
|
if ((oldcc = client_current(sc)) != NULL) {
|
||||||
oldcc->flags &= ~CLIENT_ACTIVE;
|
oldcc->flags &= ~CLIENT_ACTIVE;
|
||||||
client_draw_border(oldcc);
|
client_draw_border(oldcc);
|
||||||
}
|
}
|
||||||
@ -238,16 +235,23 @@ client_setactive(struct client_ctx *cc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct client_ctx *
|
struct client_ctx *
|
||||||
client_current(void)
|
client_current(struct screen_ctx *sc)
|
||||||
{
|
{
|
||||||
struct screen_ctx *sc;
|
struct screen_ctx *_sc;
|
||||||
struct client_ctx *cc;
|
struct client_ctx *cc;
|
||||||
|
|
||||||
TAILQ_FOREACH(sc, &Screenq, entry) {
|
if (sc) {
|
||||||
TAILQ_FOREACH(cc, &sc->clientq, entry) {
|
TAILQ_FOREACH(cc, &sc->clientq, entry) {
|
||||||
if (cc->flags & CLIENT_ACTIVE)
|
if (cc->flags & CLIENT_ACTIVE)
|
||||||
return(cc);
|
return(cc);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
TAILQ_FOREACH(_sc, &Screenq, entry) {
|
||||||
|
TAILQ_FOREACH(cc, &_sc->clientq, entry) {
|
||||||
|
if (cc->flags & CLIENT_ACTIVE)
|
||||||
|
return(cc);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
@ -527,25 +531,16 @@ client_hide(struct client_ctx *cc)
|
|||||||
{
|
{
|
||||||
XUnmapWindow(X_Dpy, cc->win);
|
XUnmapWindow(X_Dpy, cc->win);
|
||||||
|
|
||||||
if (cc->flags & CLIENT_ACTIVE)
|
if (cc->flags & CLIENT_ACTIVE) {
|
||||||
|
cc->flags &= ~CLIENT_ACTIVE;
|
||||||
xu_ewmh_net_active_window(cc->sc, None);
|
xu_ewmh_net_active_window(cc->sc, None);
|
||||||
|
}
|
||||||
cc->flags &= ~CLIENT_ACTIVE;
|
|
||||||
cc->flags |= CLIENT_HIDDEN;
|
cc->flags |= CLIENT_HIDDEN;
|
||||||
client_set_wm_state(cc, IconicState);
|
client_set_wm_state(cc, IconicState);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
client_show(struct client_ctx *cc)
|
client_show(struct client_ctx *cc)
|
||||||
{
|
|
||||||
if (cc->flags & CLIENT_HIDDEN)
|
|
||||||
client_unhide(cc);
|
|
||||||
else
|
|
||||||
client_raise(cc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
client_unhide(struct client_ctx *cc)
|
|
||||||
{
|
{
|
||||||
XMapRaised(X_Dpy, cc->win);
|
XMapRaised(X_Dpy, cc->win);
|
||||||
|
|
||||||
@ -691,7 +686,7 @@ client_cycle(struct screen_ctx *sc, int flags)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
prevcc = TAILQ_FIRST(&sc->clientq);
|
prevcc = TAILQ_FIRST(&sc->clientq);
|
||||||
oldcc = client_current();
|
oldcc = client_current(sc);
|
||||||
if (oldcc == NULL)
|
if (oldcc == NULL)
|
||||||
oldcc = (flags & CWM_CYCLE_REVERSE) ?
|
oldcc = (flags & CWM_CYCLE_REVERSE) ?
|
||||||
TAILQ_LAST(&sc->clientq, client_q) :
|
TAILQ_LAST(&sc->clientq, client_q) :
|
||||||
@ -972,12 +967,11 @@ void
|
|||||||
client_htile(struct client_ctx *cc)
|
client_htile(struct client_ctx *cc)
|
||||||
{
|
{
|
||||||
struct client_ctx *ci;
|
struct client_ctx *ci;
|
||||||
struct group_ctx *gc = cc->gc;
|
|
||||||
struct screen_ctx *sc = cc->sc;
|
struct screen_ctx *sc = cc->sc;
|
||||||
struct geom area;
|
struct geom area;
|
||||||
int i, n, mh, x, w, h;
|
int i, n, mh, x, w, h;
|
||||||
|
|
||||||
if (!gc)
|
if (!cc->gc)
|
||||||
return;
|
return;
|
||||||
i = n = 0;
|
i = n = 0;
|
||||||
|
|
||||||
@ -985,7 +979,9 @@ client_htile(struct client_ctx *cc)
|
|||||||
cc->geom.x + cc->geom.w / 2,
|
cc->geom.x + cc->geom.w / 2,
|
||||||
cc->geom.y + cc->geom.h / 2, CWM_GAP);
|
cc->geom.y + cc->geom.h / 2, CWM_GAP);
|
||||||
|
|
||||||
TAILQ_FOREACH(ci, &gc->clientq, group_entry) {
|
TAILQ_FOREACH(ci, &sc->clientq, entry) {
|
||||||
|
if (ci->gc != cc->gc)
|
||||||
|
continue;
|
||||||
if (ci->flags & CLIENT_HIDDEN ||
|
if (ci->flags & CLIENT_HIDDEN ||
|
||||||
ci->flags & CLIENT_IGNORE || (ci == cc) ||
|
ci->flags & CLIENT_IGNORE || (ci == cc) ||
|
||||||
ci->geom.x < area.x ||
|
ci->geom.x < area.x ||
|
||||||
@ -1014,7 +1010,9 @@ client_htile(struct client_ctx *cc)
|
|||||||
x = area.x;
|
x = area.x;
|
||||||
w = area.w / n;
|
w = area.w / n;
|
||||||
h = area.h - mh;
|
h = area.h - mh;
|
||||||
TAILQ_FOREACH(ci, &gc->clientq, group_entry) {
|
TAILQ_FOREACH(ci, &sc->clientq, entry) {
|
||||||
|
if (ci->gc != cc->gc)
|
||||||
|
continue;
|
||||||
if (ci->flags & CLIENT_HIDDEN ||
|
if (ci->flags & CLIENT_HIDDEN ||
|
||||||
ci->flags & CLIENT_IGNORE || (ci == cc) ||
|
ci->flags & CLIENT_IGNORE || (ci == cc) ||
|
||||||
ci->geom.x < area.x ||
|
ci->geom.x < area.x ||
|
||||||
@ -1040,12 +1038,11 @@ void
|
|||||||
client_vtile(struct client_ctx *cc)
|
client_vtile(struct client_ctx *cc)
|
||||||
{
|
{
|
||||||
struct client_ctx *ci;
|
struct client_ctx *ci;
|
||||||
struct group_ctx *gc = cc->gc;
|
|
||||||
struct screen_ctx *sc = cc->sc;
|
struct screen_ctx *sc = cc->sc;
|
||||||
struct geom area;
|
struct geom area;
|
||||||
int i, n, mw, y, w, h;
|
int i, n, mw, y, w, h;
|
||||||
|
|
||||||
if (!gc)
|
if (!cc->gc)
|
||||||
return;
|
return;
|
||||||
i = n = 0;
|
i = n = 0;
|
||||||
|
|
||||||
@ -1053,7 +1050,9 @@ client_vtile(struct client_ctx *cc)
|
|||||||
cc->geom.x + cc->geom.w / 2,
|
cc->geom.x + cc->geom.w / 2,
|
||||||
cc->geom.y + cc->geom.h / 2, CWM_GAP);
|
cc->geom.y + cc->geom.h / 2, CWM_GAP);
|
||||||
|
|
||||||
TAILQ_FOREACH(ci, &gc->clientq, group_entry) {
|
TAILQ_FOREACH(ci, &sc->clientq, entry) {
|
||||||
|
if (ci->gc != cc->gc)
|
||||||
|
continue;
|
||||||
if (ci->flags & CLIENT_HIDDEN ||
|
if (ci->flags & CLIENT_HIDDEN ||
|
||||||
ci->flags & CLIENT_IGNORE || (ci == cc) ||
|
ci->flags & CLIENT_IGNORE || (ci == cc) ||
|
||||||
ci->geom.x < area.x ||
|
ci->geom.x < area.x ||
|
||||||
@ -1082,7 +1081,9 @@ client_vtile(struct client_ctx *cc)
|
|||||||
y = area.y;
|
y = area.y;
|
||||||
h = area.h / n;
|
h = area.h / n;
|
||||||
w = area.w - mw;
|
w = area.w - mw;
|
||||||
TAILQ_FOREACH(ci, &gc->clientq, group_entry) {
|
TAILQ_FOREACH(ci, &sc->clientq, entry) {
|
||||||
|
if (ci->gc != cc->gc)
|
||||||
|
continue;
|
||||||
if (ci->flags & CLIENT_HIDDEN ||
|
if (ci->flags & CLIENT_HIDDEN ||
|
||||||
ci->flags & CLIENT_IGNORE || (ci == cc) ||
|
ci->flags & CLIENT_IGNORE || (ci == cc) ||
|
||||||
ci->geom.x < area.x ||
|
ci->geom.x < area.x ||
|
||||||
|
47
conf.c
47
conf.c
@ -36,6 +36,21 @@ static const char *conf_bind_getmask(const char *, unsigned int *);
|
|||||||
static void conf_unbind_key(struct conf *, struct bind_ctx *);
|
static void conf_unbind_key(struct conf *, struct bind_ctx *);
|
||||||
static void conf_unbind_mouse(struct conf *, struct bind_ctx *);
|
static void conf_unbind_mouse(struct conf *, struct bind_ctx *);
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
int num;
|
||||||
|
const char *name;
|
||||||
|
} group_binds[] = {
|
||||||
|
{ 0, "nogroup" },
|
||||||
|
{ 1, "one" },
|
||||||
|
{ 2, "two" },
|
||||||
|
{ 3, "three" },
|
||||||
|
{ 4, "four" },
|
||||||
|
{ 5, "five" },
|
||||||
|
{ 6, "six" },
|
||||||
|
{ 7, "seven" },
|
||||||
|
{ 8, "eight" },
|
||||||
|
{ 9, "nine" },
|
||||||
|
};
|
||||||
static int cursor_binds[] = {
|
static int cursor_binds[] = {
|
||||||
XC_left_ptr, /* CF_NORMAL */
|
XC_left_ptr, /* CF_NORMAL */
|
||||||
XC_fleur, /* CF_MOVE */
|
XC_fleur, /* CF_MOVE */
|
||||||
@ -124,7 +139,7 @@ static const struct {
|
|||||||
|
|
||||||
{ FUNC_SC(group-cycle, group_cycle, (CWM_CYCLE_FORWARD)) },
|
{ FUNC_SC(group-cycle, group_cycle, (CWM_CYCLE_FORWARD)) },
|
||||||
{ FUNC_SC(group-rcycle, group_cycle, (CWM_CYCLE_REVERSE)) },
|
{ FUNC_SC(group-rcycle, group_cycle, (CWM_CYCLE_REVERSE)) },
|
||||||
{ FUNC_SC(group-toggle-all, group_alltoggle, 0) },
|
{ FUNC_SC(group-toggle-all, group_toggle_all, 0) },
|
||||||
{ FUNC_SC(group-toggle-1, group_toggle, 1) },
|
{ FUNC_SC(group-toggle-1, group_toggle, 1) },
|
||||||
{ FUNC_SC(group-toggle-2, group_toggle, 2) },
|
{ FUNC_SC(group-toggle-2, group_toggle, 2) },
|
||||||
{ FUNC_SC(group-toggle-3, group_toggle, 3) },
|
{ FUNC_SC(group-toggle-3, group_toggle, 3) },
|
||||||
@ -266,7 +281,7 @@ conf_init(struct conf *c)
|
|||||||
c->bwidth = 1;
|
c->bwidth = 1;
|
||||||
c->mamount = 1;
|
c->mamount = 1;
|
||||||
c->snapdist = 0;
|
c->snapdist = 0;
|
||||||
c->ngroups = 10;
|
c->ngroups = 0;
|
||||||
c->nameqlen = 5;
|
c->nameqlen = 5;
|
||||||
|
|
||||||
TAILQ_INIT(&c->ignoreq);
|
TAILQ_INIT(&c->ignoreq);
|
||||||
@ -478,30 +493,28 @@ conf_screen(struct screen_ctx *sc)
|
|||||||
warnx("XftColorAllocValue: %s", Conf.color[i]);
|
warnx("XftColorAllocValue: %s", Conf.color[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (XftColorAllocName(X_Dpy, sc->visual, sc->colormap,
|
if (!XftColorAllocName(X_Dpy, sc->visual, sc->colormap,
|
||||||
Conf.color[i], &xc)) {
|
Conf.color[i], &sc->xftcolor[i])) {
|
||||||
sc->xftcolor[i] = xc;
|
|
||||||
XftColorFree(X_Dpy, sc->visual, sc->colormap, &xc);
|
|
||||||
} else {
|
|
||||||
warnx("XftColorAllocName: %s", Conf.color[i]);
|
warnx("XftColorAllocName: %s", Conf.color[i]);
|
||||||
XftColorAllocName(X_Dpy, sc->visual, sc->colormap,
|
XftColorAllocName(X_Dpy, sc->visual, sc->colormap,
|
||||||
color_binds[i], &sc->xftcolor[i]);
|
color_binds[i], &sc->xftcolor[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sc->menu.win = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, 1, 1,
|
|
||||||
Conf.bwidth,
|
|
||||||
sc->xftcolor[CWM_COLOR_MENU_FG].pixel,
|
|
||||||
sc->xftcolor[CWM_COLOR_MENU_BG].pixel);
|
|
||||||
|
|
||||||
sc->menu.xftdraw = XftDrawCreate(X_Dpy, sc->menu.win,
|
|
||||||
sc->visual, sc->colormap);
|
|
||||||
if (sc->menu.xftdraw == NULL)
|
|
||||||
errx(1, "%s: XftDrawCreate", __func__);
|
|
||||||
|
|
||||||
conf_grab_kbd(sc->rootwin);
|
conf_grab_kbd(sc->rootwin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
conf_group(struct screen_ctx *sc)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < nitems(group_binds); i++) {
|
||||||
|
group_init(sc, group_binds[i].num, group_binds[i].name);
|
||||||
|
Conf.ngroups++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
conf_bind_getmask(const char *name, unsigned int *mask)
|
conf_bind_getmask(const char *name, unsigned int *mask)
|
||||||
{
|
{
|
||||||
|
5
cwm.1
5
cwm.1
@ -23,7 +23,7 @@
|
|||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.\" For a program: program [-abc] file ...
|
.\" For a program: program [-abc] file ...
|
||||||
.Nm cwm
|
.Nm cwm
|
||||||
.Op Fl v
|
.Op Fl nv
|
||||||
.Op Fl c Ar file
|
.Op Fl c Ar file
|
||||||
.Op Fl d Ar display
|
.Op Fl d Ar display
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
@ -48,6 +48,9 @@ however,
|
|||||||
will continue to process the rest of the configuration file.
|
will continue to process the rest of the configuration file.
|
||||||
.It Fl d Ar display
|
.It Fl d Ar display
|
||||||
Specify the display to use.
|
Specify the display to use.
|
||||||
|
.It Fl n
|
||||||
|
Configtest mode.
|
||||||
|
Only check the configuration file for validity.
|
||||||
.It Fl v
|
.It Fl v
|
||||||
Verbose mode.
|
Verbose mode.
|
||||||
Multiple
|
Multiple
|
||||||
|
154
group.c
154
group.c
@ -37,37 +37,30 @@ static struct group_ctx *group_prev(struct group_ctx *);
|
|||||||
static void group_restack(struct group_ctx *);
|
static void group_restack(struct group_ctx *);
|
||||||
static void group_setactive(struct group_ctx *);
|
static void group_setactive(struct group_ctx *);
|
||||||
|
|
||||||
const char *num_to_name[] = {
|
|
||||||
"nogroup", "one", "two", "three", "four", "five", "six",
|
|
||||||
"seven", "eight", "nine"
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
void
|
||||||
group_assign(struct group_ctx *gc, struct client_ctx *cc)
|
group_assign(struct group_ctx *gc, struct client_ctx *cc)
|
||||||
{
|
{
|
||||||
if (cc->gc != NULL)
|
|
||||||
TAILQ_REMOVE(&cc->gc->clientq, cc, group_entry);
|
|
||||||
|
|
||||||
if ((gc != NULL) && (gc->num == 0))
|
if ((gc != NULL) && (gc->num == 0))
|
||||||
gc = NULL;
|
gc = NULL;
|
||||||
|
|
||||||
cc->gc = gc;
|
cc->gc = gc;
|
||||||
|
|
||||||
if (cc->gc != NULL)
|
|
||||||
TAILQ_INSERT_TAIL(&gc->clientq, cc, group_entry);
|
|
||||||
|
|
||||||
xu_ewmh_net_wm_desktop(cc);
|
xu_ewmh_net_wm_desktop(cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
group_hide(struct group_ctx *gc)
|
group_hide(struct group_ctx *gc)
|
||||||
{
|
{
|
||||||
|
struct screen_ctx *sc = gc->sc;
|
||||||
struct client_ctx *cc;
|
struct client_ctx *cc;
|
||||||
|
|
||||||
screen_updatestackingorder(gc->sc);
|
screen_updatestackingorder(gc->sc);
|
||||||
|
|
||||||
TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
|
TAILQ_FOREACH(cc, &sc->clientq, entry) {
|
||||||
if (!(cc->flags & CLIENT_STICKY))
|
if (cc->gc != gc)
|
||||||
|
continue;
|
||||||
|
if (!(cc->flags & CLIENT_STICKY) &&
|
||||||
|
!(cc->flags & CLIENT_HIDDEN))
|
||||||
client_hide(cc);
|
client_hide(cc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,13 +68,16 @@ group_hide(struct group_ctx *gc)
|
|||||||
void
|
void
|
||||||
group_show(struct group_ctx *gc)
|
group_show(struct group_ctx *gc)
|
||||||
{
|
{
|
||||||
|
struct screen_ctx *sc = gc->sc;
|
||||||
struct client_ctx *cc;
|
struct client_ctx *cc;
|
||||||
|
|
||||||
TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
|
TAILQ_FOREACH(cc, &sc->clientq, entry) {
|
||||||
if (!(cc->flags & CLIENT_STICKY))
|
if (cc->gc != gc)
|
||||||
client_unhide(cc);
|
continue;
|
||||||
|
if (!(cc->flags & CLIENT_STICKY) &&
|
||||||
|
(cc->flags & CLIENT_HIDDEN))
|
||||||
|
client_show(cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
group_restack(gc);
|
group_restack(gc);
|
||||||
group_setactive(gc);
|
group_setactive(gc);
|
||||||
}
|
}
|
||||||
@ -89,19 +85,24 @@ group_show(struct group_ctx *gc)
|
|||||||
static void
|
static void
|
||||||
group_restack(struct group_ctx *gc)
|
group_restack(struct group_ctx *gc)
|
||||||
{
|
{
|
||||||
|
struct screen_ctx *sc = gc->sc;
|
||||||
struct client_ctx *cc;
|
struct client_ctx *cc;
|
||||||
Window *winlist;
|
Window *winlist;
|
||||||
int i, lastempty = -1;
|
int i, lastempty = -1;
|
||||||
int nwins = 0, highstack = 0;
|
int nwins = 0, highstack = 0;
|
||||||
|
|
||||||
TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
|
TAILQ_FOREACH(cc, &sc->clientq, entry) {
|
||||||
|
if (cc->gc != gc)
|
||||||
|
continue;
|
||||||
if (cc->stackingorder > highstack)
|
if (cc->stackingorder > highstack)
|
||||||
highstack = cc->stackingorder;
|
highstack = cc->stackingorder;
|
||||||
}
|
}
|
||||||
winlist = xreallocarray(NULL, (highstack + 1), sizeof(*winlist));
|
winlist = xreallocarray(NULL, (highstack + 1), sizeof(*winlist));
|
||||||
|
|
||||||
/* Invert the stacking order for XRestackWindows(). */
|
/* Invert the stacking order for XRestackWindows(). */
|
||||||
TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
|
TAILQ_FOREACH(cc, &sc->clientq, entry) {
|
||||||
|
if (cc->gc != gc)
|
||||||
|
continue;
|
||||||
winlist[highstack - cc->stackingorder] = cc->win;
|
winlist[highstack - cc->stackingorder] = cc->win;
|
||||||
nwins++;
|
nwins++;
|
||||||
}
|
}
|
||||||
@ -122,16 +123,14 @@ group_restack(struct group_ctx *gc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
group_init(struct screen_ctx *sc, int num)
|
group_init(struct screen_ctx *sc, int num, const char *name)
|
||||||
{
|
{
|
||||||
struct group_ctx *gc;
|
struct group_ctx *gc;
|
||||||
|
|
||||||
gc = xmalloc(sizeof(*gc));
|
gc = xmalloc(sizeof(*gc));
|
||||||
gc->sc = sc;
|
gc->sc = sc;
|
||||||
gc->name = xstrdup(num_to_name[num]);
|
gc->name = xstrdup(name);
|
||||||
gc->num = num;
|
gc->num = num;
|
||||||
TAILQ_INIT(&gc->clientq);
|
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(&sc->groupq, gc, entry);
|
TAILQ_INSERT_TAIL(&sc->groupq, gc, entry);
|
||||||
|
|
||||||
if (num == 1)
|
if (num == 1)
|
||||||
@ -154,19 +153,15 @@ group_movetogroup(struct client_ctx *cc, int idx)
|
|||||||
struct screen_ctx *sc = cc->sc;
|
struct screen_ctx *sc = cc->sc;
|
||||||
struct group_ctx *gc;
|
struct group_ctx *gc;
|
||||||
|
|
||||||
if (idx < 0 || idx >= Conf.ngroups)
|
|
||||||
return;
|
|
||||||
|
|
||||||
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
||||||
if (gc->num == idx)
|
if (gc->num == idx) {
|
||||||
break;
|
if (cc->gc == gc)
|
||||||
|
return;
|
||||||
|
if (gc->num != 0 && group_holds_only_hidden(gc))
|
||||||
|
client_hide(cc);
|
||||||
|
group_assign(gc, cc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cc->gc == gc)
|
|
||||||
return;
|
|
||||||
if (gc->num != 0 && group_holds_only_hidden(gc))
|
|
||||||
client_hide(cc);
|
|
||||||
group_assign(gc, cc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -175,23 +170,25 @@ group_toggle_membership(struct client_ctx *cc)
|
|||||||
struct screen_ctx *sc = cc->sc;
|
struct screen_ctx *sc = cc->sc;
|
||||||
struct group_ctx *gc = sc->group_active;
|
struct group_ctx *gc = sc->group_active;
|
||||||
|
|
||||||
if (gc == cc->gc) {
|
if (cc->gc == gc) {
|
||||||
group_assign(NULL, cc);
|
group_assign(NULL, cc);
|
||||||
cc->flags |= CLIENT_UNGROUP;
|
cc->flags |= CLIENT_UNGROUP;
|
||||||
} else {
|
} else {
|
||||||
group_assign(gc, cc);
|
group_assign(gc, cc);
|
||||||
cc->flags |= CLIENT_GROUP;
|
cc->flags |= CLIENT_GROUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
client_draw_border(cc);
|
client_draw_border(cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
group_holds_only_sticky(struct group_ctx *gc)
|
group_holds_only_sticky(struct group_ctx *gc)
|
||||||
{
|
{
|
||||||
|
struct screen_ctx *sc = gc->sc;
|
||||||
struct client_ctx *cc;
|
struct client_ctx *cc;
|
||||||
|
|
||||||
TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
|
TAILQ_FOREACH(cc, &sc->clientq, entry) {
|
||||||
|
if (cc->gc != gc)
|
||||||
|
continue;
|
||||||
if (!(cc->flags & CLIENT_STICKY))
|
if (!(cc->flags & CLIENT_STICKY))
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
@ -201,46 +198,23 @@ group_holds_only_sticky(struct group_ctx *gc)
|
|||||||
int
|
int
|
||||||
group_holds_only_hidden(struct group_ctx *gc)
|
group_holds_only_hidden(struct group_ctx *gc)
|
||||||
{
|
{
|
||||||
|
struct screen_ctx *sc = gc->sc;
|
||||||
struct client_ctx *cc;
|
struct client_ctx *cc;
|
||||||
|
|
||||||
TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
|
TAILQ_FOREACH(cc, &sc->clientq, entry) {
|
||||||
|
if (cc->gc != gc)
|
||||||
|
continue;
|
||||||
if (!(cc->flags & (CLIENT_HIDDEN | CLIENT_STICKY)))
|
if (!(cc->flags & (CLIENT_HIDDEN | CLIENT_STICKY)))
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
group_hidetoggle(struct screen_ctx *sc, int idx)
|
|
||||||
{
|
|
||||||
struct group_ctx *gc;
|
|
||||||
|
|
||||||
if (idx < 0 || idx >= Conf.ngroups)
|
|
||||||
return;
|
|
||||||
|
|
||||||
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
|
||||||
if (gc->num == idx)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (group_holds_only_hidden(gc))
|
|
||||||
group_show(gc);
|
|
||||||
else {
|
|
||||||
group_hide(gc);
|
|
||||||
/* make clients stick to empty group */
|
|
||||||
if (TAILQ_EMPTY(&gc->clientq))
|
|
||||||
group_setactive(gc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
group_only(struct screen_ctx *sc, int idx)
|
group_only(struct screen_ctx *sc, int idx)
|
||||||
{
|
{
|
||||||
struct group_ctx *gc;
|
struct group_ctx *gc;
|
||||||
|
|
||||||
if (idx < 0 || idx >= Conf.ngroups)
|
|
||||||
return;
|
|
||||||
|
|
||||||
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
||||||
if (gc->num == idx)
|
if (gc->num == idx)
|
||||||
group_show(gc);
|
group_show(gc);
|
||||||
@ -249,19 +223,48 @@ group_only(struct screen_ctx *sc, int idx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
group_toggle(struct screen_ctx *sc, int idx)
|
||||||
|
{
|
||||||
|
struct group_ctx *gc;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
||||||
|
if (gc->num == idx) {
|
||||||
|
if (group_holds_only_hidden(gc))
|
||||||
|
group_show(gc);
|
||||||
|
else
|
||||||
|
group_hide(gc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
group_toggle_all(struct screen_ctx *sc)
|
||||||
|
{
|
||||||
|
struct group_ctx *gc;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
||||||
|
if (sc->hideall)
|
||||||
|
group_show(gc);
|
||||||
|
else
|
||||||
|
group_hide(gc);
|
||||||
|
}
|
||||||
|
sc->hideall = !sc->hideall;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
group_close(struct screen_ctx *sc, int idx)
|
group_close(struct screen_ctx *sc, int idx)
|
||||||
{
|
{
|
||||||
struct group_ctx *gc;
|
struct group_ctx *gc;
|
||||||
struct client_ctx *cc;
|
struct client_ctx *cc;
|
||||||
|
|
||||||
if (idx < 0 || idx >= Conf.ngroups)
|
|
||||||
return;
|
|
||||||
|
|
||||||
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
||||||
if (gc->num == idx) {
|
if (gc->num == idx) {
|
||||||
TAILQ_FOREACH(cc, &gc->clientq, group_entry)
|
TAILQ_FOREACH(cc, &sc->clientq, entry) {
|
||||||
|
if (cc->gc != gc)
|
||||||
|
continue;
|
||||||
client_close(cc);
|
client_close(cc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -286,7 +289,6 @@ group_cycle(struct screen_ctx *sc, int flags)
|
|||||||
else if (!group_holds_only_hidden(newgc))
|
else if (!group_holds_only_hidden(newgc))
|
||||||
group_hide(newgc);
|
group_hide(newgc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showgroup == NULL)
|
if (showgroup == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -318,20 +320,6 @@ group_prev(struct group_ctx *gc)
|
|||||||
newgc : TAILQ_LAST(&sc->groupq, group_q));
|
newgc : TAILQ_LAST(&sc->groupq, group_q));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
group_alltoggle(struct screen_ctx *sc)
|
|
||||||
{
|
|
||||||
struct group_ctx *gc;
|
|
||||||
|
|
||||||
TAILQ_FOREACH(gc, &sc->groupq, entry) {
|
|
||||||
if (sc->hideall)
|
|
||||||
group_show(gc);
|
|
||||||
else
|
|
||||||
group_hide(gc);
|
|
||||||
}
|
|
||||||
sc->hideall = !sc->hideall;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
group_restore(struct client_ctx *cc)
|
group_restore(struct client_ctx *cc)
|
||||||
{
|
{
|
||||||
|
45
kbfunc.c
45
kbfunc.c
@ -169,8 +169,8 @@ kbfunc_client_move_mb(void *ctx, struct cargs *cargs)
|
|||||||
CurrentTime) != GrabSuccess)
|
CurrentTime) != GrabSuccess)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
menu_windraw(sc, cc->win, "%4d, %-4d", cc->geom.x, cc->geom.y);
|
screen_prop_win_create(sc, cc->win);
|
||||||
|
screen_prop_win_draw(sc, "%+5d%+5d", cc->geom.x, cc->geom.y);
|
||||||
while (move) {
|
while (move) {
|
||||||
XMaskEvent(X_Dpy, MOUSEMASK, &ev);
|
XMaskEvent(X_Dpy, MOUSEMASK, &ev);
|
||||||
switch (ev.type) {
|
switch (ev.type) {
|
||||||
@ -193,8 +193,8 @@ kbfunc_client_move_mb(void *ctx, struct cargs *cargs)
|
|||||||
cc->geom.y + cc->geom.h + (cc->bwidth * 2),
|
cc->geom.y + cc->geom.h + (cc->bwidth * 2),
|
||||||
area.y, area.y + area.h, sc->snapdist);
|
area.y, area.y + area.h, sc->snapdist);
|
||||||
client_move(cc);
|
client_move(cc);
|
||||||
menu_windraw(sc, cc->win,
|
screen_prop_win_draw(sc,
|
||||||
"%4d, %-4d", cc->geom.x, cc->geom.y);
|
"%+5d%+5d", cc->geom.x, cc->geom.y);
|
||||||
break;
|
break;
|
||||||
case ButtonRelease:
|
case ButtonRelease:
|
||||||
move = 0;
|
move = 0;
|
||||||
@ -203,8 +203,7 @@ kbfunc_client_move_mb(void *ctx, struct cargs *cargs)
|
|||||||
}
|
}
|
||||||
if (ltime)
|
if (ltime)
|
||||||
client_move(cc);
|
client_move(cc);
|
||||||
XUnmapWindow(X_Dpy, sc->menu.win);
|
screen_prop_win_destroy(sc);
|
||||||
XReparentWindow(X_Dpy, sc->menu.win, sc->rootwin, 0, 0);
|
|
||||||
XUngrabPointer(X_Dpy, CurrentTime);
|
XUngrabPointer(X_Dpy, CurrentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,7 +257,8 @@ kbfunc_client_resize_mb(void *ctx, struct cargs *cargs)
|
|||||||
CurrentTime) != GrabSuccess)
|
CurrentTime) != GrabSuccess)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
menu_windraw(sc, cc->win, "%4d x %-4d", cc->dim.w, cc->dim.h);
|
screen_prop_win_create(sc, cc->win);
|
||||||
|
screen_prop_win_draw(sc, "%4d x %-4d", cc->dim.w, cc->dim.h);
|
||||||
while (resize) {
|
while (resize) {
|
||||||
XMaskEvent(X_Dpy, MOUSEMASK, &ev);
|
XMaskEvent(X_Dpy, MOUSEMASK, &ev);
|
||||||
switch (ev.type) {
|
switch (ev.type) {
|
||||||
@ -272,7 +272,7 @@ kbfunc_client_resize_mb(void *ctx, struct cargs *cargs)
|
|||||||
cc->geom.h = ev.xmotion.y;
|
cc->geom.h = ev.xmotion.y;
|
||||||
client_applysizehints(cc);
|
client_applysizehints(cc);
|
||||||
client_resize(cc, 1);
|
client_resize(cc, 1);
|
||||||
menu_windraw(sc, cc->win,
|
screen_prop_win_draw(sc,
|
||||||
"%4d x %-4d", cc->dim.w, cc->dim.h);
|
"%4d x %-4d", cc->dim.w, cc->dim.h);
|
||||||
break;
|
break;
|
||||||
case ButtonRelease:
|
case ButtonRelease:
|
||||||
@ -282,8 +282,7 @@ kbfunc_client_resize_mb(void *ctx, struct cargs *cargs)
|
|||||||
}
|
}
|
||||||
if (ltime)
|
if (ltime)
|
||||||
client_resize(cc, 1);
|
client_resize(cc, 1);
|
||||||
XUnmapWindow(X_Dpy, sc->menu.win);
|
screen_prop_win_destroy(sc);
|
||||||
XReparentWindow(X_Dpy, sc->menu.win, sc->rootwin, 0, 0);
|
|
||||||
XUngrabPointer(X_Dpy, CurrentTime);
|
XUngrabPointer(X_Dpy, CurrentTime);
|
||||||
|
|
||||||
/* Make sure the pointer stays within the window. */
|
/* Make sure the pointer stays within the window. */
|
||||||
@ -431,18 +430,24 @@ kbfunc_client_movetogroup(void *ctx, struct cargs *cargs)
|
|||||||
group_movetogroup(ctx, cargs->flag);
|
group_movetogroup(ctx, cargs->flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
kbfunc_group_toggle(void *ctx, struct cargs *cargs)
|
|
||||||
{
|
|
||||||
group_hidetoggle(ctx, cargs->flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
kbfunc_group_only(void *ctx, struct cargs *cargs)
|
kbfunc_group_only(void *ctx, struct cargs *cargs)
|
||||||
{
|
{
|
||||||
group_only(ctx, cargs->flag);
|
group_only(ctx, cargs->flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kbfunc_group_toggle(void *ctx, struct cargs *cargs)
|
||||||
|
{
|
||||||
|
group_toggle(ctx, cargs->flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kbfunc_group_toggle_all(void *ctx, struct cargs *cargs)
|
||||||
|
{
|
||||||
|
group_toggle_all(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
kbfunc_group_close(void *ctx, struct cargs *cargs)
|
kbfunc_group_close(void *ctx, struct cargs *cargs)
|
||||||
{
|
{
|
||||||
@ -455,12 +460,6 @@ kbfunc_group_cycle(void *ctx, struct cargs *cargs)
|
|||||||
group_cycle(ctx, cargs->flag);
|
group_cycle(ctx, cargs->flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
kbfunc_group_alltoggle(void *ctx, struct cargs *cargs)
|
|
||||||
{
|
|
||||||
group_alltoggle(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
kbfunc_menu_client(void *ctx, struct cargs *cargs)
|
kbfunc_menu_client(void *ctx, struct cargs *cargs)
|
||||||
{
|
{
|
||||||
@ -474,7 +473,7 @@ kbfunc_menu_client(void *ctx, struct cargs *cargs)
|
|||||||
if (cargs->xev == CWM_XEV_BTN)
|
if (cargs->xev == CWM_XEV_BTN)
|
||||||
mflags |= CWM_MENU_LIST;
|
mflags |= CWM_MENU_LIST;
|
||||||
|
|
||||||
old_cc = client_current();
|
old_cc = client_current(sc);
|
||||||
|
|
||||||
TAILQ_INIT(&menuq);
|
TAILQ_INIT(&menuq);
|
||||||
TAILQ_FOREACH(cc, &sc->clientq, entry) {
|
TAILQ_FOREACH(cc, &sc->clientq, entry) {
|
||||||
|
82
menu.c
82
menu.c
@ -37,6 +37,10 @@
|
|||||||
#define PROMPT_SCHAR "\xc2\xbb"
|
#define PROMPT_SCHAR "\xc2\xbb"
|
||||||
#define PROMPT_ECHAR "\xc2\xab"
|
#define PROMPT_ECHAR "\xc2\xab"
|
||||||
|
|
||||||
|
#define MENUMASK (MOUSEMASK | ButtonMotionMask | KeyPressMask | \
|
||||||
|
ExposureMask)
|
||||||
|
#define MENUGRABMASK (MOUSEMASK | ButtonMotionMask | StructureNotifyMask)
|
||||||
|
|
||||||
enum ctltype {
|
enum ctltype {
|
||||||
CTL_NONE = -1,
|
CTL_NONE = -1,
|
||||||
CTL_ERASEONE = 0, CTL_WIPE, CTL_UP, CTL_DOWN, CTL_RETURN,
|
CTL_ERASEONE = 0, CTL_WIPE, CTL_UP, CTL_DOWN, CTL_RETURN,
|
||||||
@ -45,6 +49,9 @@ enum ctltype {
|
|||||||
|
|
||||||
struct menu_ctx {
|
struct menu_ctx {
|
||||||
struct screen_ctx *sc;
|
struct screen_ctx *sc;
|
||||||
|
Window win;
|
||||||
|
XftDraw *xftdraw;
|
||||||
|
struct geom geom;
|
||||||
char searchstr[MENU_MAXENTRY + 1];
|
char searchstr[MENU_MAXENTRY + 1];
|
||||||
char dispstr[MENU_MAXENTRY*2 + 1];
|
char dispstr[MENU_MAXENTRY*2 + 1];
|
||||||
char promptstr[MENU_MAXENTRY + 1];
|
char promptstr[MENU_MAXENTRY + 1];
|
||||||
@ -55,7 +62,6 @@ struct menu_ctx {
|
|||||||
int entry;
|
int entry;
|
||||||
int num;
|
int num;
|
||||||
int flags;
|
int flags;
|
||||||
struct geom geom;
|
|
||||||
void (*match)(struct menu_q *, struct menu_q *, char *);
|
void (*match)(struct menu_q *, struct menu_q *, char *);
|
||||||
void (*print)(struct menu *, int);
|
void (*print)(struct menu *, int);
|
||||||
};
|
};
|
||||||
@ -108,27 +114,34 @@ menu_filter(struct screen_ctx *sc, struct menu_q *menuq, const char *prompt,
|
|||||||
else
|
else
|
||||||
mc.searchstr[0] = '\0';
|
mc.searchstr[0] = '\0';
|
||||||
|
|
||||||
XSelectInput(X_Dpy, sc->menu.win, MENUMASK);
|
mc.win = XCreateSimpleWindow(X_Dpy, sc->rootwin, 0, 0, 1, 1,
|
||||||
XMapRaised(X_Dpy, sc->menu.win);
|
Conf.bwidth,
|
||||||
|
sc->xftcolor[CWM_COLOR_MENU_FG].pixel,
|
||||||
|
sc->xftcolor[CWM_COLOR_MENU_BG].pixel);
|
||||||
|
mc.xftdraw = XftDrawCreate(X_Dpy, mc.win,
|
||||||
|
sc->visual, sc->colormap);
|
||||||
|
|
||||||
if (XGrabPointer(X_Dpy, sc->menu.win, False, MENUGRABMASK,
|
XSelectInput(X_Dpy, mc.win, MENUMASK);
|
||||||
|
XMapRaised(X_Dpy, mc.win);
|
||||||
|
|
||||||
|
if (XGrabPointer(X_Dpy, mc.win, False, MENUGRABMASK,
|
||||||
GrabModeAsync, GrabModeAsync, None, Conf.cursor[CF_QUESTION],
|
GrabModeAsync, GrabModeAsync, None, Conf.cursor[CF_QUESTION],
|
||||||
CurrentTime) != GrabSuccess) {
|
CurrentTime) != GrabSuccess) {
|
||||||
XUnmapWindow(X_Dpy, sc->menu.win);
|
XftDrawDestroy(mc.xftdraw);
|
||||||
return(NULL);
|
XDestroyWindow(X_Dpy, mc.win);
|
||||||
}
|
}
|
||||||
|
|
||||||
XGetInputFocus(X_Dpy, &focuswin, &focusrevert);
|
XGetInputFocus(X_Dpy, &focuswin, &focusrevert);
|
||||||
XSetInputFocus(X_Dpy, sc->menu.win, RevertToPointerRoot, CurrentTime);
|
XSetInputFocus(X_Dpy, mc.win, RevertToPointerRoot, CurrentTime);
|
||||||
|
|
||||||
/* make sure keybindings don't remove keys from the menu stream */
|
/* make sure keybindings don't remove keys from the menu stream */
|
||||||
XGrabKeyboard(X_Dpy, sc->menu.win, True,
|
XGrabKeyboard(X_Dpy, mc.win, True,
|
||||||
GrabModeAsync, GrabModeAsync, CurrentTime);
|
GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
mc.changed = 0;
|
mc.changed = 0;
|
||||||
|
|
||||||
XWindowEvent(X_Dpy, sc->menu.win, MENUMASK, &e);
|
XWindowEvent(X_Dpy, mc.win, MENUMASK, &e);
|
||||||
|
|
||||||
switch (e.type) {
|
switch (e.type) {
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
@ -159,16 +172,16 @@ out:
|
|||||||
mi = NULL;
|
mi = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
XSelectInput(X_Dpy, sc->menu.win, NoEventMask);
|
XftDrawDestroy(mc.xftdraw);
|
||||||
|
XDestroyWindow(X_Dpy, mc.win);
|
||||||
|
|
||||||
XSetInputFocus(X_Dpy, focuswin, focusrevert, CurrentTime);
|
XSetInputFocus(X_Dpy, focuswin, focusrevert, CurrentTime);
|
||||||
/* restore if user didn't move */
|
/* restore if user didn't move */
|
||||||
xu_ptr_getpos(sc->rootwin, &xcur, &ycur);
|
xu_ptr_getpos(sc->rootwin, &xcur, &ycur);
|
||||||
if (xcur == mc.geom.x && ycur == mc.geom.y)
|
if (xcur == mc.geom.x && ycur == mc.geom.y)
|
||||||
xu_ptr_setpos(sc->rootwin, xsave, ysave);
|
xu_ptr_setpos(sc->rootwin, xsave, ysave);
|
||||||
XUngrabPointer(X_Dpy, CurrentTime);
|
|
||||||
|
|
||||||
XMoveResizeWindow(X_Dpy, sc->menu.win, 0, 0, 1, 1);
|
XUngrabPointer(X_Dpy, CurrentTime);
|
||||||
XUnmapWindow(X_Dpy, sc->menu.win);
|
|
||||||
XUngrabKeyboard(X_Dpy, CurrentTime);
|
XUngrabKeyboard(X_Dpy, CurrentTime);
|
||||||
|
|
||||||
return(mi);
|
return(mi);
|
||||||
@ -378,12 +391,12 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq)
|
|||||||
if (mc->geom.x != xsave || mc->geom.y != ysave)
|
if (mc->geom.x != xsave || mc->geom.y != ysave)
|
||||||
xu_ptr_setpos(sc->rootwin, mc->geom.x, mc->geom.y);
|
xu_ptr_setpos(sc->rootwin, mc->geom.x, mc->geom.y);
|
||||||
|
|
||||||
XClearWindow(X_Dpy, sc->menu.win);
|
XClearWindow(X_Dpy, mc->win);
|
||||||
XMoveResizeWindow(X_Dpy, sc->menu.win, mc->geom.x, mc->geom.y,
|
XMoveResizeWindow(X_Dpy, mc->win, mc->geom.x, mc->geom.y,
|
||||||
mc->geom.w, mc->geom.h);
|
mc->geom.w, mc->geom.h);
|
||||||
|
|
||||||
n = 1;
|
n = 1;
|
||||||
XftDrawStringUtf8(sc->menu.xftdraw,
|
XftDrawStringUtf8(mc->xftdraw,
|
||||||
&sc->xftcolor[CWM_COLOR_MENU_FONT], sc->xftfont,
|
&sc->xftcolor[CWM_COLOR_MENU_FONT], sc->xftfont,
|
||||||
0, sc->xftfont->ascent,
|
0, sc->xftfont->ascent,
|
||||||
(const FcChar8*)mc->dispstr, strlen(mc->dispstr));
|
(const FcChar8*)mc->dispstr, strlen(mc->dispstr));
|
||||||
@ -395,7 +408,7 @@ menu_draw(struct menu_ctx *mc, struct menu_q *menuq, struct menu_q *resultq)
|
|||||||
if (mc->geom.y + y > area.h)
|
if (mc->geom.y + y > area.h)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
XftDrawStringUtf8(sc->menu.xftdraw,
|
XftDrawStringUtf8(mc->xftdraw,
|
||||||
&sc->xftcolor[CWM_COLOR_MENU_FONT], sc->xftfont,
|
&sc->xftcolor[CWM_COLOR_MENU_FONT], sc->xftfont,
|
||||||
0, y,
|
0, y,
|
||||||
(const FcChar8*)mi->print, strlen(mi->print));
|
(const FcChar8*)mi->print, strlen(mi->print));
|
||||||
@ -420,11 +433,11 @@ menu_draw_entry(struct menu_ctx *mc, struct menu_q *resultq,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
color = (active) ? CWM_COLOR_MENU_FG : CWM_COLOR_MENU_BG;
|
color = (active) ? CWM_COLOR_MENU_FG : CWM_COLOR_MENU_BG;
|
||||||
XftDrawRect(sc->menu.xftdraw, &sc->xftcolor[color], 0,
|
XftDrawRect(mc->xftdraw, &sc->xftcolor[color], 0,
|
||||||
(sc->xftfont->height + 1) * entry, mc->geom.w,
|
(sc->xftfont->height + 1) * entry, mc->geom.w,
|
||||||
(sc->xftfont->height + 1) + sc->xftfont->descent);
|
(sc->xftfont->height + 1) + sc->xftfont->descent);
|
||||||
color = (active) ? CWM_COLOR_MENU_FONT_SEL : CWM_COLOR_MENU_FONT;
|
color = (active) ? CWM_COLOR_MENU_FONT_SEL : CWM_COLOR_MENU_FONT;
|
||||||
XftDrawStringUtf8(sc->menu.xftdraw,
|
XftDrawStringUtf8(mc->xftdraw,
|
||||||
&sc->xftcolor[color], sc->xftfont,
|
&sc->xftcolor[color], sc->xftfont,
|
||||||
0, (sc->xftfont->height + 1) * entry + sc->xftfont->ascent + 1,
|
0, (sc->xftfont->height + 1) * entry + sc->xftfont->ascent + 1,
|
||||||
(const FcChar8*)mi->print, strlen(mi->print));
|
(const FcChar8*)mi->print, strlen(mi->print));
|
||||||
@ -604,34 +617,3 @@ menuq_clear(struct menu_q *mq)
|
|||||||
free(mi);
|
free(mi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
menu_windraw(struct screen_ctx *sc, Window win, const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
int i;
|
|
||||||
char *text;
|
|
||||||
XGlyphInfo extents;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
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);
|
|
||||||
|
|
||||||
XReparentWindow(X_Dpy, sc->menu.win, win, 0, 0);
|
|
||||||
XMoveResizeWindow(X_Dpy, sc->menu.win, 0, 0,
|
|
||||||
extents.xOff, sc->xftfont->height);
|
|
||||||
XMapWindow(X_Dpy, sc->menu.win);
|
|
||||||
XClearWindow(X_Dpy, sc->menu.win);
|
|
||||||
|
|
||||||
XftDrawStringUtf8(sc->menu.xftdraw, &sc->xftcolor[CWM_COLOR_MENU_FONT],
|
|
||||||
sc->xftfont, 0, sc->xftfont->ascent + 1,
|
|
||||||
(const FcChar8*)text, strlen(text));
|
|
||||||
|
|
||||||
free(text);
|
|
||||||
}
|
|
||||||
|
56
screen.c
56
screen.c
@ -24,6 +24,7 @@
|
|||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -40,7 +41,6 @@ screen_init(int which)
|
|||||||
Window *wins, w0, w1, active = None;
|
Window *wins, w0, w1, active = None;
|
||||||
XSetWindowAttributes rootattr;
|
XSetWindowAttributes rootattr;
|
||||||
unsigned int nwins, w;
|
unsigned int nwins, w;
|
||||||
int i;
|
|
||||||
|
|
||||||
sc = xmalloc(sizeof(*sc));
|
sc = xmalloc(sizeof(*sc));
|
||||||
|
|
||||||
@ -60,14 +60,11 @@ screen_init(int which)
|
|||||||
xu_ewmh_net_supported(sc);
|
xu_ewmh_net_supported(sc);
|
||||||
xu_ewmh_net_supported_wm_check(sc);
|
xu_ewmh_net_supported_wm_check(sc);
|
||||||
|
|
||||||
|
conf_group(sc);
|
||||||
screen_update_geometry(sc);
|
screen_update_geometry(sc);
|
||||||
|
|
||||||
for (i = 0; i < Conf.ngroups; i++)
|
|
||||||
group_init(sc, i);
|
|
||||||
|
|
||||||
xu_ewmh_net_desktop_names(sc);
|
xu_ewmh_net_desktop_names(sc);
|
||||||
xu_ewmh_net_wm_desktop_viewport(sc);
|
xu_ewmh_net_number_of_desktops(sc);
|
||||||
xu_ewmh_net_wm_number_of_desktops(sc);
|
|
||||||
xu_ewmh_net_showing_desktop(sc);
|
xu_ewmh_net_showing_desktop(sc);
|
||||||
xu_ewmh_net_virtual_roots(sc);
|
xu_ewmh_net_virtual_roots(sc);
|
||||||
active = xu_ewmh_get_net_active_window(sc);
|
active = xu_ewmh_get_net_active_window(sc);
|
||||||
@ -106,7 +103,7 @@ screen_find(Window win)
|
|||||||
if (sc->rootwin == win)
|
if (sc->rootwin == win)
|
||||||
return(sc);
|
return(sc);
|
||||||
}
|
}
|
||||||
warnx("%s: failure win 0x%lu\n", __func__, win);
|
warnx("%s: failure win 0x%lx", __func__, win);
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,6 +214,7 @@ screen_update_geometry(struct screen_ctx *sc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
xu_ewmh_net_desktop_geometry(sc);
|
xu_ewmh_net_desktop_geometry(sc);
|
||||||
|
xu_ewmh_net_desktop_viewport(sc);
|
||||||
xu_ewmh_net_workarea(sc);
|
xu_ewmh_net_workarea(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,3 +251,47 @@ screen_assert_clients_within(struct screen_ctx *sc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
screen_prop_win_create(struct screen_ctx *sc, Window win)
|
||||||
|
{
|
||||||
|
sc->prop.win = XCreateSimpleWindow(X_Dpy, win, 0, 0, 1, 1, 0,
|
||||||
|
sc->xftcolor[CWM_COLOR_MENU_BG].pixel,
|
||||||
|
sc->xftcolor[CWM_COLOR_MENU_BG].pixel);
|
||||||
|
sc->prop.xftdraw = XftDrawCreate(X_Dpy, sc->prop.win,
|
||||||
|
sc->visual, sc->colormap);
|
||||||
|
|
||||||
|
XMapWindow(X_Dpy, sc->prop.win);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
screen_prop_win_destroy(struct screen_ctx *sc)
|
||||||
|
{
|
||||||
|
XftDrawDestroy(sc->prop.xftdraw);
|
||||||
|
XDestroyWindow(X_Dpy, sc->prop.win);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
XResizeWindow(X_Dpy, sc->prop.win, extents.xOff, sc->xftfont->height);
|
||||||
|
XClearWindow(X_Dpy, sc->prop.win);
|
||||||
|
XftDrawStringUtf8(sc->prop.xftdraw, &sc->xftcolor[CWM_COLOR_MENU_FONT],
|
||||||
|
sc->xftfont, 0, sc->xftfont->ascent + 1,
|
||||||
|
(const FcChar8*)text, strlen(text));
|
||||||
|
|
||||||
|
free(text);
|
||||||
|
}
|
||||||
|
85
xevents.c
85
xevents.c
@ -75,11 +75,15 @@ static void
|
|||||||
xev_handle_maprequest(XEvent *ee)
|
xev_handle_maprequest(XEvent *ee)
|
||||||
{
|
{
|
||||||
XMapRequestEvent *e = &ee->xmaprequest;
|
XMapRequestEvent *e = &ee->xmaprequest;
|
||||||
struct client_ctx *cc = NULL, *old_cc;
|
struct screen_ctx *sc;
|
||||||
|
struct client_ctx *cc, *old_cc;
|
||||||
|
|
||||||
LOG_DEBUG3("window: 0x%lx", e->window);
|
LOG_DEBUG3("parent: 0x%lx window: 0x%lx", e->parent, e->window);
|
||||||
|
|
||||||
if ((old_cc = client_current()) != NULL)
|
if ((sc = screen_find(e->parent)) == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((old_cc = client_current(sc)) != NULL)
|
||||||
client_ptrsave(old_cc);
|
client_ptrsave(old_cc);
|
||||||
|
|
||||||
if ((cc = client_find(e->window)) == NULL)
|
if ((cc = client_find(e->window)) == NULL)
|
||||||
@ -207,11 +211,9 @@ xev_handle_propertynotify(XEvent *ee)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TAILQ_FOREACH(sc, &Screenq, entry) {
|
if (e->atom == ewmh[_NET_DESKTOP_NAMES]) {
|
||||||
if (sc->rootwin == e->window) {
|
if ((sc = screen_find(e->window)) != NULL)
|
||||||
if (e->atom == ewmh[_NET_DESKTOP_NAMES])
|
xu_ewmh_net_desktop_names(sc);
|
||||||
xu_ewmh_net_desktop_names(sc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -238,7 +240,11 @@ xev_handle_buttonpress(XEvent *ee)
|
|||||||
struct screen_ctx *sc;
|
struct screen_ctx *sc;
|
||||||
struct bind_ctx *mb;
|
struct bind_ctx *mb;
|
||||||
|
|
||||||
LOG_DEBUG3("window: 0x%lx", e->window);
|
LOG_DEBUG3("root: 0x%lx window: 0x%lx subwindow: 0x%lx",
|
||||||
|
e->root, e->window, e->subwindow);
|
||||||
|
|
||||||
|
if ((sc = screen_find(e->root)) == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
e->state &= ~IGNOREMODMASK;
|
e->state &= ~IGNOREMODMASK;
|
||||||
|
|
||||||
@ -246,22 +252,17 @@ xev_handle_buttonpress(XEvent *ee)
|
|||||||
if (e->button == mb->press.button && e->state == mb->modmask)
|
if (e->button == mb->press.button && e->state == mb->modmask)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mb == NULL)
|
if (mb == NULL)
|
||||||
return;
|
return;
|
||||||
mb->cargs->xev = CWM_XEV_BTN;
|
mb->cargs->xev = CWM_XEV_BTN;
|
||||||
switch (mb->context) {
|
switch (mb->context) {
|
||||||
case CWM_CONTEXT_CC:
|
case CWM_CONTEXT_CC:
|
||||||
if (((cc = client_find(e->window)) == NULL) &&
|
if (((cc = client_find(e->window)) == NULL) &&
|
||||||
(cc = client_current()) == NULL)
|
((cc = client_current(sc)) == NULL))
|
||||||
return;
|
return;
|
||||||
(*mb->callback)(cc, mb->cargs);
|
(*mb->callback)(cc, mb->cargs);
|
||||||
break;
|
break;
|
||||||
case CWM_CONTEXT_SC:
|
case CWM_CONTEXT_SC:
|
||||||
if (e->window != e->root)
|
|
||||||
return;
|
|
||||||
if ((sc = screen_find(e->window)) == NULL)
|
|
||||||
return;
|
|
||||||
(*mb->callback)(sc, mb->cargs);
|
(*mb->callback)(sc, mb->cargs);
|
||||||
break;
|
break;
|
||||||
case CWM_CONTEXT_NONE:
|
case CWM_CONTEXT_NONE:
|
||||||
@ -276,7 +277,8 @@ xev_handle_buttonrelease(XEvent *ee)
|
|||||||
XButtonEvent *e = &ee->xbutton;
|
XButtonEvent *e = &ee->xbutton;
|
||||||
struct client_ctx *cc;
|
struct client_ctx *cc;
|
||||||
|
|
||||||
LOG_DEBUG3("window: 0x%lx", ee->xbutton.window);
|
LOG_DEBUG3("root: 0x%lx window: 0x%lx subwindow: 0x%lx",
|
||||||
|
e->root, e->window, e->subwindow);
|
||||||
|
|
||||||
if ((cc = client_find(e->window)) != NULL) {
|
if ((cc = client_find(e->window)) != NULL) {
|
||||||
if (cc->flags & (CLIENT_ACTIVE | CLIENT_HIGHLIGHT)) {
|
if (cc->flags & (CLIENT_ACTIVE | CLIENT_HIGHLIGHT)) {
|
||||||
@ -296,7 +298,11 @@ xev_handle_keypress(XEvent *ee)
|
|||||||
KeySym keysym, skeysym;
|
KeySym keysym, skeysym;
|
||||||
unsigned int modshift;
|
unsigned int modshift;
|
||||||
|
|
||||||
LOG_DEBUG3("window: 0x%lx", e->window);
|
LOG_DEBUG3("root: 0x%lx window: 0x%lx subwindow: 0x%lx",
|
||||||
|
e->root, e->window, e->subwindow);
|
||||||
|
|
||||||
|
if ((sc = screen_find(e->root)) == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
keysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 0);
|
keysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 0);
|
||||||
skeysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 1);
|
skeysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 1);
|
||||||
@ -315,20 +321,17 @@ xev_handle_keypress(XEvent *ee)
|
|||||||
if (kb->press.keysym == ((modshift == 0) ? keysym : skeysym))
|
if (kb->press.keysym == ((modshift == 0) ? keysym : skeysym))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kb == NULL)
|
if (kb == NULL)
|
||||||
return;
|
return;
|
||||||
kb->cargs->xev = CWM_XEV_KEY;
|
kb->cargs->xev = CWM_XEV_KEY;
|
||||||
switch (kb->context) {
|
switch (kb->context) {
|
||||||
case CWM_CONTEXT_CC:
|
case CWM_CONTEXT_CC:
|
||||||
if (((cc = client_find(e->window)) == NULL) &&
|
if (((cc = client_find(e->subwindow)) == NULL) &&
|
||||||
(cc = client_current()) == NULL)
|
((cc = client_current(sc)) == NULL))
|
||||||
return;
|
return;
|
||||||
(*kb->callback)(cc, kb->cargs);
|
(*kb->callback)(cc, kb->cargs);
|
||||||
break;
|
break;
|
||||||
case CWM_CONTEXT_SC:
|
case CWM_CONTEXT_SC:
|
||||||
if ((sc = screen_find(e->window)) == NULL)
|
|
||||||
return;
|
|
||||||
(*kb->callback)(sc, kb->cargs);
|
(*kb->callback)(sc, kb->cargs);
|
||||||
break;
|
break;
|
||||||
case CWM_CONTEXT_NONE:
|
case CWM_CONTEXT_NONE:
|
||||||
@ -349,7 +352,8 @@ xev_handle_keyrelease(XEvent *ee)
|
|||||||
KeySym keysym;
|
KeySym keysym;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
LOG_DEBUG3("window: 0x%lx", e->window);
|
LOG_DEBUG3("root: 0x%lx window: 0x%lx subwindow: 0x%lx",
|
||||||
|
e->root, e->window, e->subwindow);
|
||||||
|
|
||||||
if ((sc = screen_find(e->root)) == NULL)
|
if ((sc = screen_find(e->root)) == NULL)
|
||||||
return;
|
return;
|
||||||
@ -357,7 +361,7 @@ xev_handle_keyrelease(XEvent *ee)
|
|||||||
keysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 0);
|
keysym = XkbKeycodeToKeysym(X_Dpy, e->keycode, 0, 0);
|
||||||
for (i = 0; i < nitems(modkeys); i++) {
|
for (i = 0; i < nitems(modkeys); i++) {
|
||||||
if (keysym == modkeys[i]) {
|
if (keysym == modkeys[i]) {
|
||||||
if ((cc = client_current()) != NULL) {
|
if ((cc = client_current(sc)) != NULL) {
|
||||||
if (sc->cycling) {
|
if (sc->cycling) {
|
||||||
sc->cycling = 0;
|
sc->cycling = 0;
|
||||||
client_mtf(cc);
|
client_mtf(cc);
|
||||||
@ -393,7 +397,7 @@ xev_handle_clientmessage(XEvent *ee)
|
|||||||
}
|
}
|
||||||
} else if (e->message_type == ewmh[_NET_ACTIVE_WINDOW]) {
|
} else if (e->message_type == ewmh[_NET_ACTIVE_WINDOW]) {
|
||||||
if ((cc = client_find(e->window)) != NULL) {
|
if ((cc = client_find(e->window)) != NULL) {
|
||||||
if ((old_cc = client_current()) != NULL)
|
if ((old_cc = client_current(NULL)) != NULL)
|
||||||
client_ptrsave(old_cc);
|
client_ptrsave(old_cc);
|
||||||
client_show(cc);
|
client_show(cc);
|
||||||
client_ptrwarp(cc);
|
client_ptrwarp(cc);
|
||||||
@ -408,7 +412,9 @@ xev_handle_clientmessage(XEvent *ee)
|
|||||||
if (e->data.l[0] == (unsigned long)-1)
|
if (e->data.l[0] == (unsigned long)-1)
|
||||||
group_movetogroup(cc, 0);
|
group_movetogroup(cc, 0);
|
||||||
else
|
else
|
||||||
group_movetogroup(cc, e->data.l[0]);
|
if (e->data.l[0] >= 0 &&
|
||||||
|
e->data.l[0] < Conf.ngroups)
|
||||||
|
group_movetogroup(cc, e->data.l[0]);
|
||||||
}
|
}
|
||||||
} else if (e->message_type == ewmh[_NET_WM_STATE]) {
|
} else if (e->message_type == ewmh[_NET_WM_STATE]) {
|
||||||
if ((cc = client_find(e->window)) != NULL) {
|
if ((cc = client_find(e->window)) != NULL) {
|
||||||
@ -417,7 +423,9 @@ xev_handle_clientmessage(XEvent *ee)
|
|||||||
}
|
}
|
||||||
} else if (e->message_type == ewmh[_NET_CURRENT_DESKTOP]) {
|
} else if (e->message_type == ewmh[_NET_CURRENT_DESKTOP]) {
|
||||||
if ((sc = screen_find(e->window)) != NULL) {
|
if ((sc = screen_find(e->window)) != NULL) {
|
||||||
group_only(sc, e->data.l[0]);
|
if (e->data.l[0] >= 0 &&
|
||||||
|
e->data.l[0] < Conf.ngroups)
|
||||||
|
group_only(sc, e->data.l[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -425,20 +433,17 @@ xev_handle_clientmessage(XEvent *ee)
|
|||||||
static void
|
static void
|
||||||
xev_handle_randr(XEvent *ee)
|
xev_handle_randr(XEvent *ee)
|
||||||
{
|
{
|
||||||
XRRScreenChangeNotifyEvent *rev = (XRRScreenChangeNotifyEvent *)ee;
|
XRRScreenChangeNotifyEvent *e = (XRRScreenChangeNotifyEvent *)ee;
|
||||||
struct screen_ctx *sc;
|
struct screen_ctx *sc;
|
||||||
int i;
|
|
||||||
|
|
||||||
LOG_DEBUG3("new size: %d/%d", rev->width, rev->height);
|
LOG_DEBUG3("size: %d/%d", e->width, e->height);
|
||||||
|
|
||||||
i = XRRRootToScreen(X_Dpy, rev->root);
|
if ((sc = screen_find(e->root)) == NULL)
|
||||||
TAILQ_FOREACH(sc, &Screenq, entry) {
|
return;
|
||||||
if (sc->which == i) {
|
|
||||||
XRRUpdateConfiguration(ee);
|
XRRUpdateConfiguration(ee);
|
||||||
screen_update_geometry(sc);
|
screen_update_geometry(sc);
|
||||||
screen_assert_clients_within(sc);
|
screen_assert_clients_within(sc);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -479,9 +484,9 @@ xev_process(void)
|
|||||||
|
|
||||||
while (XPending(X_Dpy)) {
|
while (XPending(X_Dpy)) {
|
||||||
XNextEvent(X_Dpy, &e);
|
XNextEvent(X_Dpy, &e);
|
||||||
if (e.type - Conf.xrandr_event_base == RRScreenChangeNotify)
|
if ((e.type - Conf.xrandr_event_base) == RRScreenChangeNotify)
|
||||||
xev_handle_randr(&e);
|
xev_handle_randr(&e);
|
||||||
else if (e.type < LASTEvent && xev_handlers[e.type] != NULL)
|
else if ((e.type < LASTEvent) && (xev_handlers[e.type] != NULL))
|
||||||
(*xev_handlers[e.type])(&e);
|
(*xev_handlers[e.type])(&e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
22
xutil.c
22
xutil.c
@ -128,6 +128,16 @@ xu_ewmh_net_desktop_geometry(struct screen_ctx *sc)
|
|||||||
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)geom , 2);
|
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)geom , 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xu_ewmh_net_desktop_viewport(struct screen_ctx *sc)
|
||||||
|
{
|
||||||
|
long viewports[2] = {0, 0};
|
||||||
|
|
||||||
|
/* We don't support large desktops, so this is (0, 0). */
|
||||||
|
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_VIEWPORT],
|
||||||
|
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)viewports, 2);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xu_ewmh_net_workarea(struct screen_ctx *sc)
|
xu_ewmh_net_workarea(struct screen_ctx *sc)
|
||||||
{
|
{
|
||||||
@ -212,17 +222,7 @@ xu_ewmh_get_net_active_window(struct screen_ctx *sc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xu_ewmh_net_wm_desktop_viewport(struct screen_ctx *sc)
|
xu_ewmh_net_number_of_desktops(struct screen_ctx *sc)
|
||||||
{
|
|
||||||
long viewports[2] = {0, 0};
|
|
||||||
|
|
||||||
/* We don't support large desktops, so this is (0, 0). */
|
|
||||||
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_DESKTOP_VIEWPORT],
|
|
||||||
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)viewports, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
xu_ewmh_net_wm_number_of_desktops(struct screen_ctx *sc)
|
|
||||||
{
|
{
|
||||||
long ndesks = Conf.ngroups;
|
long ndesks = Conf.ngroups;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user