cvsimport

* refs/heads/master: (21 commits)
  Lost fix from r1.112; add comment.
  Mechanical change: group->gc
  Add consistent checks against NULL.
  Move client cycle grab/ungrab into a more relevant place; while here, update comments about why we need to grab/ungrab the keyboard.
  Re-add lost chunk in group_cycle from r1.113.
  Further simplify _NET_WM_DESKTOP handling using new group_assign().
  oops; remove left over debug print
  Allowing sending a valid 'nogroup' (0) group_ctx to group_assign() (since we init all groups), though assigning the client's group to NULL for 'sticky'; use this simplification in a few places (others to follow).
  Split out sticky mode checks and the restoring of a client's group and _NET_WM_DESKTOP from the config-based auto-grouping; no (intentional) behavior changes.  Needed for further work in cleaning up this area.
  Implement _NET_CLIENT_LIST_STACKING (from Thomas Admin), but bottom-to-top order, as per spec (notified Thomas as well).
  Don't allow freeze operations on fullscreen (consistent with what fullscreen does).
  Sort _NET_WM_STATE Atoms like the spec.
  Move CLIENT_STICKY logic from client hide/unhide to group hide/unhide; rationale being that clients should be able to hide/unhide independently of group switching.
  Add Xkb modifier to ignore mask; from Alexander Polakov.
  Fix whitespace.
  Add client freeze extension to _NET_WM_STATE Atom, allowing flag to persist. As usual with new Atoms, requires X restart.
  _NET_WM_STATE_STICKY implies only sticky at the group/desktop level, not position and size; based on discussion with a few.
  Instead of special casing the 'term' and 'lock' commands, go back to keeping them hidden; showing them has apparently caused confusion/angst.
  Leave command list order from .cwmrc alone; remove sort.
  Bring group and client cycle closer together.
  ...
This commit is contained in:
okan
2015-08-28 12:07:28 +00:00
11 changed files with 254 additions and 184 deletions

View File

@@ -64,12 +64,12 @@ size_t strlcpy(char *, const char *, size_t);
#define CONFFILE ".cwmrc" #define CONFFILE ".cwmrc"
#define WMNAME "CWM" #define WMNAME "CWM"
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) #define BUTTONMASK (ButtonPressMask | ButtonReleaseMask)
#define MOUSEMASK (BUTTONMASK|PointerMotionMask) #define MOUSEMASK (BUTTONMASK | PointerMotionMask)
#define MENUMASK (MOUSEMASK|ButtonMotionMask|ExposureMask) #define MENUMASK (MOUSEMASK | ButtonMotionMask | ExposureMask)
#define MENUGRABMASK (MOUSEMASK|ButtonMotionMask|StructureNotifyMask) #define MENUGRABMASK (MOUSEMASK | ButtonMotionMask | StructureNotifyMask)
#define KEYMASK (KeyPressMask|ExposureMask) #define KEYMASK (KeyPressMask | ExposureMask)
#define IGNOREMODMASK (LockMask|Mod2Mask) #define IGNOREMODMASK (LockMask | Mod2Mask | 0x2000)
/* kb movement */ /* kb movement */
#define CWM_MOVE 0x0001 #define CWM_MOVE 0x0001
@@ -168,6 +168,7 @@ struct client_ctx {
TAILQ_ENTRY(client_ctx) entry; TAILQ_ENTRY(client_ctx) entry;
TAILQ_ENTRY(client_ctx) group_entry; TAILQ_ENTRY(client_ctx) group_entry;
struct screen_ctx *sc; struct screen_ctx *sc;
struct group_ctx *gc;
Window win; Window win;
Colormap colormap; Colormap colormap;
unsigned int bwidth; /* border width */ unsigned int bwidth; /* border width */
@@ -219,7 +220,6 @@ struct client_ctx {
char *name; char *name;
char *label; char *label;
char *matchname; char *matchname;
struct group_ctx *group;
XClassHint ch; XClassHint ch;
XWMHints *wmh; XWMHints *wmh;
}; };
@@ -373,6 +373,7 @@ enum {
_NET_SUPPORTING_WM_CHECK, _NET_SUPPORTING_WM_CHECK,
_NET_ACTIVE_WINDOW, _NET_ACTIVE_WINDOW,
_NET_CLIENT_LIST, _NET_CLIENT_LIST,
_NET_CLIENT_LIST_STACKING,
_NET_NUMBER_OF_DESKTOPS, _NET_NUMBER_OF_DESKTOPS,
_NET_CURRENT_DESKTOP, _NET_CURRENT_DESKTOP,
_NET_DESKTOP_VIEWPORT, _NET_DESKTOP_VIEWPORT,
@@ -385,13 +386,14 @@ enum {
_NET_WM_DESKTOP, _NET_WM_DESKTOP,
_NET_CLOSE_WINDOW, _NET_CLOSE_WINDOW,
_NET_WM_STATE, _NET_WM_STATE,
#define _NET_WM_STATES_NITEMS 6 #define _NET_WM_STATES_NITEMS 7
_NET_WM_STATE_STICKY, _NET_WM_STATE_STICKY,
_NET_WM_STATE_MAXIMIZED_VERT, _NET_WM_STATE_MAXIMIZED_VERT,
_NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_HORZ,
_NET_WM_STATE_HIDDEN, _NET_WM_STATE_HIDDEN,
_NET_WM_STATE_FULLSCREEN, _NET_WM_STATE_FULLSCREEN,
_NET_WM_STATE_DEMANDS_ATTENTION, _NET_WM_STATE_DEMANDS_ATTENTION,
_CWM_WM_STATE_FREEZE,
EWMH_NITEMS EWMH_NITEMS
}; };
enum { enum {
@@ -445,7 +447,8 @@ void client_warp(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_alltoggle(struct screen_ctx *);
void group_autogroup(struct client_ctx *); void group_assign(struct group_ctx *, 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); void group_hidetoggle(struct screen_ctx *, int);
@@ -454,6 +457,7 @@ int group_holds_only_sticky(struct group_ctx *);
void group_init(struct screen_ctx *, int); void group_init(struct screen_ctx *, int);
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);
int group_restore(struct client_ctx *);
void group_show(struct group_ctx *); void group_show(struct group_ctx *);
void group_toggle_membership_enter(struct client_ctx *); void group_toggle_membership_enter(struct client_ctx *);
void group_toggle_membership_leave(struct client_ctx *); void group_toggle_membership_leave(struct client_ctx *);
@@ -582,6 +586,7 @@ 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_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_active_window(struct screen_ctx *, Window); void xu_ewmh_net_active_window(struct screen_ctx *, Window);
void xu_ewmh_net_wm_desktop_viewport(struct screen_ctx *); void xu_ewmh_net_wm_desktop_viewport(struct screen_ctx *);
void xu_ewmh_net_wm_number_of_desktops(struct screen_ctx *); void xu_ewmh_net_wm_number_of_desktops(struct screen_ctx *);

View File

@@ -112,6 +112,7 @@ client_init(Window win, struct screen_ctx *sc)
TAILQ_INSERT_TAIL(&sc->clientq, cc, entry); TAILQ_INSERT_TAIL(&sc->clientq, cc, entry);
xu_ewmh_net_client_list(sc); xu_ewmh_net_client_list(sc);
xu_ewmh_net_client_list_stacking(sc);
xu_ewmh_restore_net_wm_state(cc); xu_ewmh_restore_net_wm_state(cc);
if (client_get_wm_state(cc) == IconicState) if (client_get_wm_state(cc) == IconicState)
@@ -119,9 +120,17 @@ client_init(Window win, struct screen_ctx *sc)
else else
client_unhide(cc); client_unhide(cc);
if (mapped) if (mapped) {
group_autogroup(cc); if (group_restore(cc))
goto out;
if (group_autogroup(cc))
goto out;
if (Conf.flags & CONF_STICKY_GROUPS)
group_assign(sc->group_active, cc);
else
group_assign(NULL, cc);
}
out:
XSync(X_Dpy, False); XSync(X_Dpy, False);
XUngrabServer(X_Dpy); XUngrabServer(X_Dpy);
@@ -152,9 +161,10 @@ client_delete(struct client_ctx *cc)
TAILQ_REMOVE(&sc->clientq, cc, entry); TAILQ_REMOVE(&sc->clientq, cc, entry);
xu_ewmh_net_client_list(sc); xu_ewmh_net_client_list(sc);
xu_ewmh_net_client_list_stacking(sc);
if (cc->group != NULL) if (cc->gc != NULL)
TAILQ_REMOVE(&cc->group->clientq, cc, group_entry); TAILQ_REMOVE(&cc->gc->clientq, cc, group_entry);
if (cc == client_current()) if (cc == client_current())
client_none(sc); client_none(sc);
@@ -194,7 +204,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())) { if ((oldcc = client_current()) != NULL) {
oldcc->flags &= ~CLIENT_ACTIVE; oldcc->flags &= ~CLIENT_ACTIVE;
client_draw_border(oldcc); client_draw_border(oldcc);
} }
@@ -233,10 +243,15 @@ client_current(void)
void void
client_toggle_freeze(struct client_ctx *cc) client_toggle_freeze(struct client_ctx *cc)
{ {
if (cc->flags & CLIENT_FULLSCREEN)
return;
if (cc->flags & CLIENT_FREEZE) if (cc->flags & CLIENT_FREEZE)
cc->flags &= ~CLIENT_FREEZE; cc->flags &= ~CLIENT_FREEZE;
else else
cc->flags |= CLIENT_FREEZE; cc->flags |= CLIENT_FREEZE;
xu_ewmh_set_net_wm_state(cc);
} }
void void
@@ -299,7 +314,7 @@ client_toggle_maximize(struct client_ctx *cc)
struct screen_ctx *sc = cc->sc; struct screen_ctx *sc = cc->sc;
struct geom area; struct geom area;
if (cc->flags & (CLIENT_FREEZE|CLIENT_STICKY)) if (cc->flags & CLIENT_FREEZE)
return; return;
if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_MAXIMIZED) { if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_MAXIMIZED) {
@@ -344,7 +359,7 @@ client_toggle_vmaximize(struct client_ctx *cc)
struct screen_ctx *sc = cc->sc; struct screen_ctx *sc = cc->sc;
struct geom area; struct geom area;
if (cc->flags & (CLIENT_FREEZE|CLIENT_STICKY)) if (cc->flags & CLIENT_FREEZE)
return; return;
if (cc->flags & CLIENT_VMAXIMIZED) { if (cc->flags & CLIENT_VMAXIMIZED) {
@@ -376,7 +391,7 @@ client_toggle_hmaximize(struct client_ctx *cc)
struct screen_ctx *sc = cc->sc; struct screen_ctx *sc = cc->sc;
struct geom area; struct geom area;
if (cc->flags & (CLIENT_FREEZE|CLIENT_STICKY)) if (cc->flags & CLIENT_FREEZE)
return; return;
if (cc->flags & CLIENT_HMAXIMIZED) { if (cc->flags & CLIENT_HMAXIMIZED) {
@@ -491,9 +506,6 @@ client_ptrsave(struct client_ctx *cc)
void void
client_hide(struct client_ctx *cc) client_hide(struct client_ctx *cc)
{ {
if (cc->flags & CLIENT_STICKY)
return;
XUnmapWindow(X_Dpy, cc->win); XUnmapWindow(X_Dpy, cc->win);
cc->flags &= ~CLIENT_ACTIVE; cc->flags &= ~CLIENT_ACTIVE;
@@ -507,9 +519,6 @@ client_hide(struct client_ctx *cc)
void void
client_unhide(struct client_ctx *cc) client_unhide(struct client_ctx *cc)
{ {
if (cc->flags & CLIENT_STICKY)
return;
XMapRaised(X_Dpy, cc->win); XMapRaised(X_Dpy, cc->win);
cc->flags &= ~CLIENT_HIDDEN; cc->flags &= ~CLIENT_HIDDEN;
@@ -647,29 +656,33 @@ match:
void void
client_cycle(struct screen_ctx *sc, int flags) client_cycle(struct screen_ctx *sc, int flags)
{ {
struct client_ctx *oldcc, *newcc; struct client_ctx *newcc, *oldcc;
int again = 1; int again = 1;
/* For X apps that ignore events. */
XGrabKeyboard(X_Dpy, sc->rootwin, True,
GrabModeAsync, GrabModeAsync, CurrentTime);
if (TAILQ_EMPTY(&sc->clientq)) if (TAILQ_EMPTY(&sc->clientq))
return; return;
oldcc = client_current(); oldcc = client_current();
if (oldcc == NULL) if (oldcc == NULL)
oldcc = ((flags & CWM_RCYCLE) ? oldcc = (flags & CWM_RCYCLE) ?
TAILQ_LAST(&sc->clientq, client_ctx_q) : TAILQ_LAST(&sc->clientq, client_ctx_q) :
TAILQ_FIRST(&sc->clientq)); TAILQ_FIRST(&sc->clientq);
newcc = oldcc; newcc = oldcc;
while (again) { while (again) {
again = 0; again = 0;
newcc = ((flags & CWM_RCYCLE) ? client_prev(newcc) : newcc = (flags & CWM_RCYCLE) ? client_prev(newcc) :
client_next(newcc)); client_next(newcc);
/* Only cycle visible and non-ignored windows. */ /* Only cycle visible and non-ignored windows. */
if ((newcc->flags & (CLIENT_HIDDEN|CLIENT_IGNORE)) if ((newcc->flags & (CLIENT_HIDDEN | CLIENT_IGNORE))
|| ((flags & CWM_INGROUP) && || ((flags & CWM_INGROUP) &&
(newcc->group != oldcc->group))) (newcc->gc != oldcc->gc)))
again = 1; again = 1;
/* Is oldcc the only non-hidden window? */ /* Is oldcc the only non-hidden window? */
@@ -694,9 +707,10 @@ client_cycle_leave(struct screen_ctx *sc)
sc->cycling = 0; sc->cycling = 0;
if ((cc = client_current())) { if ((cc = client_current()) != NULL) {
client_mtf(cc); client_mtf(cc);
group_toggle_membership_leave(cc); cc->flags &= ~CLIENT_HIGHLIGHT;
client_draw_border(cc);
XUngrabKeyboard(X_Dpy, CurrentTime); XUngrabKeyboard(X_Dpy, CurrentTime);
} }
} }
@@ -705,20 +719,20 @@ static struct client_ctx *
client_next(struct client_ctx *cc) client_next(struct client_ctx *cc)
{ {
struct screen_ctx *sc = cc->sc; struct screen_ctx *sc = cc->sc;
struct client_ctx *ccc; struct client_ctx *newcc;
return(((ccc = TAILQ_NEXT(cc, entry)) != NULL) ? return(((newcc = TAILQ_NEXT(cc, entry)) != NULL) ?
ccc : TAILQ_FIRST(&sc->clientq)); newcc : TAILQ_FIRST(&sc->clientq));
} }
static struct client_ctx * static struct client_ctx *
client_prev(struct client_ctx *cc) client_prev(struct client_ctx *cc)
{ {
struct screen_ctx *sc = cc->sc; struct screen_ctx *sc = cc->sc;
struct client_ctx *ccc; struct client_ctx *newcc;
return(((ccc = TAILQ_PREV(cc, client_ctx_q, entry)) != NULL) ? return(((newcc = TAILQ_PREV(cc, client_ctx_q, entry)) != NULL) ?
ccc : TAILQ_LAST(&sc->clientq, client_ctx_q)); newcc : TAILQ_LAST(&sc->clientq, client_ctx_q));
} }
static void static void
@@ -727,7 +741,7 @@ client_placecalc(struct client_ctx *cc)
struct screen_ctx *sc = cc->sc; struct screen_ctx *sc = cc->sc;
int xslack, yslack; int xslack, yslack;
if (cc->hint.flags & (USPosition|PPosition)) { if (cc->hint.flags & (USPosition | PPosition)) {
/* /*
* Ignore XINERAMA screens, just make sure it's somewhere * Ignore XINERAMA screens, just make sure it's somewhere
* in the virtual desktop. else it stops people putting xterms * in the virtual desktop. else it stops people putting xterms
@@ -901,8 +915,8 @@ client_transient(struct client_ctx *cc)
Window trans; Window trans;
if (XGetTransientForHint(X_Dpy, cc->win, &trans)) { if (XGetTransientForHint(X_Dpy, cc->win, &trans)) {
if ((tc = client_find(trans)) && tc->group) { if ((tc = client_find(trans)) != NULL && tc->gc) {
group_movetogroup(cc, tc->group->num); group_movetogroup(cc, tc->gc->num);
if (tc->flags & CLIENT_IGNORE) if (tc->flags & CLIENT_IGNORE)
cc->flags |= CLIENT_IGNORE; cc->flags |= CLIENT_IGNORE;
} }
@@ -947,7 +961,7 @@ 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->group; 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, h, w; int i, n, mh, x, h, w;
@@ -1006,7 +1020,7 @@ 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->group; 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, h, w; int i, n, mw, y, h, w;

79
conf.c
View File

@@ -40,7 +40,7 @@ static void conf_unbind_mouse(struct conf *, struct binding *);
int int
conf_cmd_add(struct conf *c, const char *name, const char *path) conf_cmd_add(struct conf *c, const char *name, const char *path)
{ {
struct cmd *cmd, *prev; struct cmd *cmd;
cmd = xmalloc(sizeof(*cmd)); cmd = xmalloc(sizeof(*cmd));
@@ -55,13 +55,6 @@ conf_cmd_add(struct conf *c, const char *name, const char *path)
TAILQ_INSERT_TAIL(&c->cmdq, cmd, entry); TAILQ_INSERT_TAIL(&c->cmdq, cmd, entry);
/* keep queue sorted by name */
while ((prev = TAILQ_PREV(cmd, cmd_q, entry)) &&
(strcmp(prev->name, cmd->name) > 0)) {
TAILQ_REMOVE(&c->cmdq, cmd, entry);
TAILQ_INSERT_BEFORE(prev, cmd, entry);
}
return(1); return(1);
} }
@@ -224,18 +217,18 @@ static const struct {
{ "M-j", "movedown" }, { "M-j", "movedown" },
{ "M-k", "moveup" }, { "M-k", "moveup" },
{ "M-l", "moveright" }, { "M-l", "moveright" },
{ "M-H", "bigmoveleft" }, { "MS-h", "bigmoveleft" },
{ "M-J", "bigmovedown" }, { "MS-j", "bigmovedown" },
{ "M-K", "bigmoveup" }, { "MS-k", "bigmoveup" },
{ "M-L", "bigmoveright" }, { "MS-l", "bigmoveright" },
{ "CM-h", "resizeleft" }, { "CM-h", "resizeleft" },
{ "CM-j", "resizedown" }, { "CM-j", "resizedown" },
{ "CM-k", "resizeup" }, { "CM-k", "resizeup" },
{ "CM-l", "resizeright" }, { "CM-l", "resizeright" },
{ "CM-H", "bigresizeleft" }, { "CMS-h", "bigresizeleft" },
{ "CM-J", "bigresizedown" }, { "CMS-j", "bigresizedown" },
{ "CM-K", "bigresizeup" }, { "CMS-k", "bigresizeup" },
{ "CM-L", "bigresizeright" }, { "CMS-l", "bigresizeright" },
{ "C-Left", "ptrmoveleft" }, { "C-Left", "ptrmoveleft" },
{ "C-Down", "ptrmovedown" }, { "C-Down", "ptrmovedown" },
{ "C-Up", "ptrmoveup" }, { "C-Up", "ptrmoveup" },
@@ -397,9 +390,9 @@ static const struct {
{ "cyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_CYCLE} }, { "cyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_CYCLE} },
{ "rcyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_RCYCLE} }, { "rcyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_RCYCLE} },
{ "cycleingroup", kbfunc_client_cycle, CWM_WIN, { "cycleingroup", kbfunc_client_cycle, CWM_WIN,
{.i = CWM_CYCLE|CWM_INGROUP} }, {.i = (CWM_CYCLE | CWM_INGROUP)} },
{ "rcycleingroup", kbfunc_client_cycle, CWM_WIN, { "rcycleingroup", kbfunc_client_cycle, CWM_WIN,
{.i = CWM_RCYCLE|CWM_INGROUP} }, {.i = (CWM_RCYCLE | CWM_INGROUP)} },
{ "grouptoggle", kbfunc_client_grouptoggle, CWM_WIN, {.i = 0}}, { "grouptoggle", kbfunc_client_grouptoggle, CWM_WIN, {.i = 0}},
{ "sticky", kbfunc_client_toggle_sticky, CWM_WIN, {0} }, { "sticky", kbfunc_client_toggle_sticky, CWM_WIN, {0} },
{ "fullscreen", kbfunc_client_toggle_fullscreen, CWM_WIN, {0} }, { "fullscreen", kbfunc_client_toggle_fullscreen, CWM_WIN, {0} },
@@ -415,53 +408,53 @@ static const struct {
{ "terminal", kbfunc_term, 0, {0} }, { "terminal", kbfunc_term, 0, {0} },
{ "lock", kbfunc_lock, 0, {0} }, { "lock", kbfunc_lock, 0, {0} },
{ "moveup", kbfunc_client_moveresize, CWM_WIN, { "moveup", kbfunc_client_moveresize, CWM_WIN,
{.i = (CWM_UP|CWM_MOVE)} }, {.i = (CWM_UP | CWM_MOVE)} },
{ "movedown", kbfunc_client_moveresize, CWM_WIN, { "movedown", kbfunc_client_moveresize, CWM_WIN,
{.i = (CWM_DOWN|CWM_MOVE)} }, {.i = (CWM_DOWN | CWM_MOVE)} },
{ "moveright", kbfunc_client_moveresize, CWM_WIN, { "moveright", kbfunc_client_moveresize, CWM_WIN,
{.i = (CWM_RIGHT|CWM_MOVE)} }, {.i = (CWM_RIGHT | CWM_MOVE)} },
{ "moveleft", kbfunc_client_moveresize, CWM_WIN, { "moveleft", kbfunc_client_moveresize, CWM_WIN,
{.i = (CWM_LEFT|CWM_MOVE)} }, {.i = (CWM_LEFT | CWM_MOVE)} },
{ "bigmoveup", kbfunc_client_moveresize, CWM_WIN, { "bigmoveup", kbfunc_client_moveresize, CWM_WIN,
{.i = (CWM_UP|CWM_MOVE|CWM_BIGMOVE)} }, {.i = (CWM_UP | CWM_MOVE | CWM_BIGMOVE)} },
{ "bigmovedown", kbfunc_client_moveresize, CWM_WIN, { "bigmovedown", kbfunc_client_moveresize, CWM_WIN,
{.i = (CWM_DOWN|CWM_MOVE|CWM_BIGMOVE)} }, {.i = (CWM_DOWN | CWM_MOVE | CWM_BIGMOVE)} },
{ "bigmoveright", kbfunc_client_moveresize, CWM_WIN, { "bigmoveright", kbfunc_client_moveresize, CWM_WIN,
{.i = (CWM_RIGHT|CWM_MOVE|CWM_BIGMOVE)} }, {.i = (CWM_RIGHT | CWM_MOVE | CWM_BIGMOVE)} },
{ "bigmoveleft", kbfunc_client_moveresize, CWM_WIN, { "bigmoveleft", kbfunc_client_moveresize, CWM_WIN,
{.i = (CWM_LEFT|CWM_MOVE|CWM_BIGMOVE)} }, {.i = (CWM_LEFT | CWM_MOVE | CWM_BIGMOVE)} },
{ "resizeup", kbfunc_client_moveresize, CWM_WIN, { "resizeup", kbfunc_client_moveresize, CWM_WIN,
{.i = (CWM_UP|CWM_RESIZE)} }, {.i = (CWM_UP | CWM_RESIZE)} },
{ "resizedown", kbfunc_client_moveresize, CWM_WIN, { "resizedown", kbfunc_client_moveresize, CWM_WIN,
{.i = (CWM_DOWN|CWM_RESIZE)} }, {.i = (CWM_DOWN | CWM_RESIZE)} },
{ "resizeright", kbfunc_client_moveresize, CWM_WIN, { "resizeright", kbfunc_client_moveresize, CWM_WIN,
{.i = (CWM_RIGHT|CWM_RESIZE)} }, {.i = (CWM_RIGHT | CWM_RESIZE)} },
{ "resizeleft", kbfunc_client_moveresize, CWM_WIN, { "resizeleft", kbfunc_client_moveresize, CWM_WIN,
{.i = (CWM_LEFT|CWM_RESIZE)} }, {.i = (CWM_LEFT | CWM_RESIZE)} },
{ "bigresizeup", kbfunc_client_moveresize, CWM_WIN, { "bigresizeup", kbfunc_client_moveresize, CWM_WIN,
{.i = (CWM_UP|CWM_RESIZE|CWM_BIGMOVE)} }, {.i = (CWM_UP | CWM_RESIZE | CWM_BIGMOVE)} },
{ "bigresizedown", kbfunc_client_moveresize, CWM_WIN, { "bigresizedown", kbfunc_client_moveresize, CWM_WIN,
{.i = (CWM_DOWN|CWM_RESIZE|CWM_BIGMOVE)} }, {.i = (CWM_DOWN | CWM_RESIZE | CWM_BIGMOVE)} },
{ "bigresizeright", kbfunc_client_moveresize, CWM_WIN, { "bigresizeright", kbfunc_client_moveresize, CWM_WIN,
{.i = (CWM_RIGHT|CWM_RESIZE|CWM_BIGMOVE)} }, {.i = (CWM_RIGHT | CWM_RESIZE | CWM_BIGMOVE)} },
{ "bigresizeleft", kbfunc_client_moveresize, CWM_WIN, { "bigresizeleft", kbfunc_client_moveresize, CWM_WIN,
{.i = (CWM_LEFT|CWM_RESIZE|CWM_BIGMOVE)} }, {.i = (CWM_LEFT | CWM_RESIZE | CWM_BIGMOVE)} },
{ "ptrmoveup", kbfunc_client_moveresize, 0, { "ptrmoveup", kbfunc_client_moveresize, 0,
{.i = (CWM_UP|CWM_PTRMOVE)} }, {.i = (CWM_UP | CWM_PTRMOVE)} },
{ "ptrmovedown", kbfunc_client_moveresize, 0, { "ptrmovedown", kbfunc_client_moveresize, 0,
{.i = (CWM_DOWN|CWM_PTRMOVE)} }, {.i = (CWM_DOWN | CWM_PTRMOVE)} },
{ "ptrmoveleft", kbfunc_client_moveresize, 0, { "ptrmoveleft", kbfunc_client_moveresize, 0,
{.i = (CWM_LEFT|CWM_PTRMOVE)} }, {.i = (CWM_LEFT | CWM_PTRMOVE)} },
{ "ptrmoveright", kbfunc_client_moveresize, 0, { "ptrmoveright", kbfunc_client_moveresize, 0,
{.i = (CWM_RIGHT|CWM_PTRMOVE)} }, {.i = (CWM_RIGHT | CWM_PTRMOVE)} },
{ "bigptrmoveup", kbfunc_client_moveresize, 0, { "bigptrmoveup", kbfunc_client_moveresize, 0,
{.i = (CWM_UP|CWM_PTRMOVE|CWM_BIGMOVE)} }, {.i = (CWM_UP | CWM_PTRMOVE | CWM_BIGMOVE)} },
{ "bigptrmovedown", kbfunc_client_moveresize, 0, { "bigptrmovedown", kbfunc_client_moveresize, 0,
{.i = (CWM_DOWN|CWM_PTRMOVE|CWM_BIGMOVE)} }, {.i = (CWM_DOWN | CWM_PTRMOVE | CWM_BIGMOVE)} },
{ "bigptrmoveleft", kbfunc_client_moveresize, 0, { "bigptrmoveleft", kbfunc_client_moveresize, 0,
{.i = (CWM_LEFT|CWM_PTRMOVE|CWM_BIGMOVE)} }, {.i = (CWM_LEFT | CWM_PTRMOVE | CWM_BIGMOVE)} },
{ "bigptrmoveright", kbfunc_client_moveresize, 0, { "bigptrmoveright", kbfunc_client_moveresize, 0,
{.i = (CWM_RIGHT|CWM_PTRMOVE|CWM_BIGMOVE)} }, {.i = (CWM_RIGHT | CWM_PTRMOVE | CWM_BIGMOVE)} },
{ "htile", kbfunc_tile, CWM_WIN, {.i = CWM_TILE_HORIZ} }, { "htile", kbfunc_tile, CWM_WIN, {.i = CWM_TILE_HORIZ} },
{ "vtile", kbfunc_tile, CWM_WIN, {.i = CWM_TILE_VERT} }, { "vtile", kbfunc_tile, CWM_WIN, {.i = CWM_TILE_VERT} },
{ "window_lower", kbfunc_client_lower, CWM_WIN, {0} }, { "window_lower", kbfunc_client_lower, CWM_WIN, {0} },
@@ -675,6 +668,7 @@ static char *ewmhints[] = {
"_NET_SUPPORTING_WM_CHECK", "_NET_SUPPORTING_WM_CHECK",
"_NET_ACTIVE_WINDOW", "_NET_ACTIVE_WINDOW",
"_NET_CLIENT_LIST", "_NET_CLIENT_LIST",
"_NET_CLIENT_LIST_STACKING",
"_NET_NUMBER_OF_DESKTOPS", "_NET_NUMBER_OF_DESKTOPS",
"_NET_CURRENT_DESKTOP", "_NET_CURRENT_DESKTOP",
"_NET_DESKTOP_VIEWPORT", "_NET_DESKTOP_VIEWPORT",
@@ -693,6 +687,7 @@ static char *ewmhints[] = {
"_NET_WM_STATE_HIDDEN", "_NET_WM_STATE_HIDDEN",
"_NET_WM_STATE_FULLSCREEN", "_NET_WM_STATE_FULLSCREEN",
"_NET_WM_STATE_DEMANDS_ATTENTION", "_NET_WM_STATE_DEMANDS_ATTENTION",
"_CWM_WM_STATE_FREEZE",
}; };
void void

4
cwm.1
View File

@@ -117,9 +117,9 @@ Toggle maximization of current window.
Toggle vertical maximization of current window. Toggle vertical maximization of current window.
.It Ic CMS-= .It Ic CMS-=
Toggle horizontal maximization of current window. Toggle horizontal maximization of current window.
.It Ic C-[Up|Down|Left|Right] .It Ic C-[Up | Down | Left | Right]
Move pointer by a small amount. Move pointer by a small amount.
.It Ic CS-[Up|Down|Left|Right] .It Ic CS-[Up | Down | Left | Right]
Move pointer by a large amount; see Move pointer by a large amount; see
.Xr cwmrc 5 . .Xr cwmrc 5 .
.It Ic M-[hjkl] .It Ic M-[hjkl]

150
group.c
View File

@@ -32,7 +32,8 @@
#include "calmwm.h" #include "calmwm.h"
static void group_assign(struct group_ctx *, struct client_ctx *); 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_restack(struct group_ctx *);
static void group_setactive(struct group_ctx *); static void group_setactive(struct group_ctx *);
@@ -41,15 +42,18 @@ const char *num_to_name[] = {
"seven", "eight", "nine" "seven", "eight", "nine"
}; };
static void void
group_assign(struct group_ctx *gc, struct client_ctx *cc) group_assign(struct group_ctx *gc, struct client_ctx *cc)
{ {
if (cc->group != NULL) if (cc->gc != NULL)
TAILQ_REMOVE(&cc->group->clientq, cc, group_entry); TAILQ_REMOVE(&cc->gc->clientq, cc, group_entry);
cc->group = gc; if ((gc != NULL) && (gc->num == 0))
gc = NULL;
if (cc->group != NULL) cc->gc = gc;
if (cc->gc != NULL)
TAILQ_INSERT_TAIL(&gc->clientq, cc, group_entry); TAILQ_INSERT_TAIL(&gc->clientq, cc, group_entry);
xu_ewmh_net_wm_desktop(cc); xu_ewmh_net_wm_desktop(cc);
@@ -62,8 +66,10 @@ group_hide(struct group_ctx *gc)
screen_updatestackingorder(gc->sc); screen_updatestackingorder(gc->sc);
TAILQ_FOREACH(cc, &gc->clientq, group_entry) TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
client_hide(cc); if (!(cc->flags & CLIENT_STICKY))
client_hide(cc);
}
} }
void void
@@ -71,8 +77,10 @@ group_show(struct group_ctx *gc)
{ {
struct client_ctx *cc; struct client_ctx *cc;
TAILQ_FOREACH(cc, &gc->clientq, group_entry) TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
client_unhide(cc); if (!(cc->flags & CLIENT_STICKY))
client_unhide(cc);
}
group_restack(gc); group_restack(gc);
group_setactive(gc); group_setactive(gc);
@@ -154,7 +162,7 @@ group_movetogroup(struct client_ctx *cc, int idx)
break; break;
} }
if (cc->group == gc) if (cc->gc == gc)
return; return;
if (group_holds_only_hidden(gc)) if (group_holds_only_hidden(gc))
client_hide(cc); client_hide(cc);
@@ -167,7 +175,7 @@ group_toggle_membership_enter(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->group) { if (gc == cc->gc) {
group_assign(NULL, cc); group_assign(NULL, cc);
cc->flags |= CLIENT_UNGROUP; cc->flags |= CLIENT_UNGROUP;
} else { } else {
@@ -255,36 +263,31 @@ group_only(struct screen_ctx *sc, int idx)
} }
} }
/*
* Cycle through active groups. If none exist, then just stay put.
*/
void void
group_cycle(struct screen_ctx *sc, int flags) group_cycle(struct screen_ctx *sc, int flags)
{ {
struct group_ctx *gc, *showgroup = NULL; struct group_ctx *newgc, *oldgc, *showgroup = NULL;
if (((gc = sc->group_active)) == NULL) oldgc = sc->group_active;
errx(1, "group_cycle: no active group");
newgc = oldgc;
for (;;) { for (;;) {
gc = (flags & CWM_RCYCLE) ? TAILQ_PREV(gc, group_ctx_q, newgc = (flags & CWM_RCYCLE) ? group_prev(newgc) :
entry) : TAILQ_NEXT(gc, entry); group_next(newgc);
if (gc == NULL)
gc = (flags & CWM_RCYCLE) ? TAILQ_LAST(&sc->groupq, if (newgc == oldgc)
group_ctx_q) : TAILQ_FIRST(&sc->groupq);
if (gc == sc->group_active)
break; break;
if (!group_holds_only_sticky(gc) && showgroup == NULL) if (!group_holds_only_sticky(newgc) && showgroup == NULL)
showgroup = gc; showgroup = newgc;
else if (!group_holds_only_hidden(gc)) else if (!group_holds_only_hidden(newgc))
group_hide(gc); group_hide(newgc);
} }
if (showgroup == NULL) if (showgroup == NULL)
return; return;
group_hide(sc->group_active); group_hide(oldgc);
if (group_holds_only_hidden(showgroup)) if (group_holds_only_hidden(showgroup))
group_show(showgroup); group_show(showgroup);
@@ -292,6 +295,26 @@ group_cycle(struct screen_ctx *sc, int flags)
group_setactive(showgroup); group_setactive(showgroup);
} }
static struct group_ctx *
group_next(struct group_ctx *gc)
{
struct screen_ctx *sc = gc->sc;
struct group_ctx *newgc;
return(((newgc = TAILQ_NEXT(gc, entry)) != NULL) ?
newgc : TAILQ_FIRST(&sc->groupq));
}
static struct group_ctx *
group_prev(struct group_ctx *gc)
{
struct screen_ctx *sc = gc->sc;
struct group_ctx *newgc;
return(((newgc = TAILQ_PREV(gc, group_ctx_q, entry)) != NULL) ?
newgc : TAILQ_LAST(&sc->groupq, group_ctx_q));
}
void void
group_alltoggle(struct screen_ctx *sc) group_alltoggle(struct screen_ctx *sc)
{ {
@@ -306,51 +329,58 @@ group_alltoggle(struct screen_ctx *sc)
sc->hideall = !sc->hideall; sc->hideall = !sc->hideall;
} }
void int
group_restore(struct client_ctx *cc)
{
struct screen_ctx *sc = cc->sc;
struct group_ctx *gc;
int num;
long *grpnum;
if (xu_getprop(cc->win, ewmh[_NET_WM_DESKTOP], XA_CARDINAL, 1L,
(unsigned char **)&grpnum) <= 0)
return(0);
num = (*grpnum == -1) ? 0 : *grpnum;
num = MIN(num, (CALMWM_NGROUPS - 1));
XFree(grpnum);
TAILQ_FOREACH(gc, &sc->groupq, entry) {
if (gc->num == num) {
group_assign(gc, cc);
return(1);
}
}
return(0);
}
int
group_autogroup(struct client_ctx *cc) group_autogroup(struct client_ctx *cc)
{ {
struct screen_ctx *sc = cc->sc; struct screen_ctx *sc = cc->sc;
struct autogroupwin *aw; struct autogroupwin *aw;
struct group_ctx *gc; struct group_ctx *gc;
int num = -2, both_match = 0; int num = -1, both_match = 0;
long *grpnum;
if (cc->ch.res_class == NULL || cc->ch.res_name == NULL) if (cc->ch.res_class == NULL || cc->ch.res_name == NULL)
return; return(0);
if (xu_getprop(cc->win, ewmh[_NET_WM_DESKTOP], TAILQ_FOREACH(aw, &Conf.autogroupq, entry) {
XA_CARDINAL, 1, (unsigned char **)&grpnum) > 0) { if (strcmp(aw->class, cc->ch.res_class) == 0) {
num = *grpnum; if ((aw->name != NULL) &&
if (num > CALMWM_NGROUPS || num < -1) (strcmp(aw->name, cc->ch.res_name) == 0)) {
num = CALMWM_NGROUPS - 1; num = aw->num;
XFree(grpnum); both_match = 1;
} else { } else if (aw->name == NULL && !both_match)
TAILQ_FOREACH(aw, &Conf.autogroupq, entry) { num = aw->num;
if (strcmp(aw->class, cc->ch.res_class) == 0) {
if ((aw->name != NULL) &&
(strcmp(aw->name, cc->ch.res_name) == 0)) {
num = aw->num;
both_match = 1;
} else if (aw->name == NULL && !both_match)
num = aw->num;
}
} }
} }
if ((num == -1) || (num == 0)) {
group_assign(NULL, cc);
return;
}
TAILQ_FOREACH(gc, &sc->groupq, entry) { TAILQ_FOREACH(gc, &sc->groupq, entry) {
if (gc->num == num) { if (gc->num == num) {
group_assign(gc, cc); group_assign(gc, cc);
return; return(1);
} }
} }
return(0);
if (Conf.flags & CONF_STICKY_GROUPS)
group_assign(sc->group_active, cc);
else
group_assign(NULL, cc);
} }

View File

@@ -61,7 +61,7 @@ kbfunc_client_moveresize(struct client_ctx *cc, union arg *arg)
int x, y, flags, amt; int x, y, flags, amt;
unsigned int mx, my; unsigned int mx, my;
if (cc->flags & (CLIENT_FREEZE|CLIENT_STICKY)) if (cc->flags & CLIENT_FREEZE)
return; return;
mx = my = 0; mx = my = 0;
@@ -177,8 +177,13 @@ kbfunc_menu_cmd(struct client_ctx *cc, union arg *arg)
struct menu_q menuq; struct menu_q menuq;
TAILQ_INIT(&menuq); TAILQ_INIT(&menuq);
TAILQ_FOREACH(cmd, &Conf.cmdq, entry) TAILQ_FOREACH(cmd, &Conf.cmdq, entry) {
if ((strcmp(cmd->name, "lock") == 0) ||
(strcmp(cmd->name, "term") == 0))
continue;
/* search_match_text() needs mi->text */
menuq_add(&menuq, cmd, "%s", cmd->name); menuq_add(&menuq, cmd, "%s", cmd->name);
}
if ((mi = menu_filter(sc, &menuq, "application", NULL, 0, if ((mi = menu_filter(sc, &menuq, "application", NULL, 0,
search_match_text, search_print_cmd)) != NULL) search_match_text, search_print_cmd)) != NULL)
@@ -215,13 +220,7 @@ kbfunc_menu_group(struct client_ctx *cc, union arg *arg)
void void
kbfunc_client_cycle(struct client_ctx *cc, union arg *arg) kbfunc_client_cycle(struct client_ctx *cc, union arg *arg)
{ {
struct screen_ctx *sc = cc->sc; client_cycle(cc->sc, arg->i);
/* XXX for X apps that ignore events */
XGrabKeyboard(X_Dpy, sc->rootwin, True,
GrabModeAsync, GrabModeAsync, CurrentTime);
client_cycle(sc, arg->i);
} }
void void
@@ -466,7 +465,7 @@ void
kbfunc_client_grouptoggle(struct client_ctx *cc, union arg *arg) kbfunc_client_grouptoggle(struct client_ctx *cc, union arg *arg)
{ {
if (arg->i == 0) { if (arg->i == 0) {
/* XXX for stupid X apps like xpdf and gvim */ /* For X apps that steal events. */
XGrabKeyboard(X_Dpy, cc->win, True, XGrabKeyboard(X_Dpy, cc->win, True,
GrabModeAsync, GrabModeAsync, CurrentTime); GrabModeAsync, GrabModeAsync, CurrentTime);
} }

View File

@@ -72,7 +72,7 @@ mousefunc_client_resize(struct client_ctx *cc, union arg *arg)
struct screen_ctx *sc = cc->sc; struct screen_ctx *sc = cc->sc;
int x = cc->geom.x, y = cc->geom.y; int x = cc->geom.x, y = cc->geom.y;
if (cc->flags & (CLIENT_FREEZE|CLIENT_STICKY)) if (cc->flags & CLIENT_FREEZE)
return; return;
client_raise(cc); client_raise(cc);
@@ -128,7 +128,7 @@ mousefunc_client_move(struct client_ctx *cc, union arg *arg)
client_raise(cc); client_raise(cc);
if (cc->flags & (CLIENT_FREEZE|CLIENT_STICKY)) if (cc->flags & CLIENT_FREEZE)
return; return;
if (xu_ptr_grab(cc->win, MOUSEMASK, Conf.cursor[CF_MOVE]) < 0) if (xu_ptr_grab(cc->win, MOUSEMASK, Conf.cursor[CF_MOVE]) < 0)
@@ -233,8 +233,12 @@ mousefunc_menu_cmd(struct client_ctx *cc, union arg *arg)
struct menu_q menuq; struct menu_q menuq;
TAILQ_INIT(&menuq); TAILQ_INIT(&menuq);
TAILQ_FOREACH(cmd, &Conf.cmdq, entry) TAILQ_FOREACH(cmd, &Conf.cmdq, entry) {
if ((strcmp(cmd->name, "lock") == 0) ||
(strcmp(cmd->name, "term") == 0))
continue;
menuq_add(&menuq, cmd, NULL); menuq_add(&menuq, cmd, NULL);
}
if ((mi = menu_filter(sc, &menuq, NULL, NULL, CWM_MENU_LIST, if ((mi = menu_filter(sc, &menuq, NULL, NULL, CWM_MENU_LIST,
NULL, search_print_cmd)) != NULL) NULL, search_print_cmd)) != NULL)

View File

@@ -67,12 +67,12 @@ screen_init(int which)
xu_ewmh_net_virtual_roots(sc); xu_ewmh_net_virtual_roots(sc);
rootattr.cursor = Conf.cursor[CF_NORMAL]; rootattr.cursor = Conf.cursor[CF_NORMAL];
rootattr.event_mask = SubstructureRedirectMask|SubstructureNotifyMask| rootattr.event_mask = SubstructureRedirectMask |
PropertyChangeMask|EnterWindowMask|LeaveWindowMask| SubstructureNotifyMask | PropertyChangeMask | EnterWindowMask |
ColormapChangeMask|BUTTONMASK; LeaveWindowMask | ColormapChangeMask | BUTTONMASK;
XChangeWindowAttributes(X_Dpy, sc->rootwin, XChangeWindowAttributes(X_Dpy, sc->rootwin,
CWEventMask|CWCursor, &rootattr); (CWEventMask | CWCursor), &rootattr);
/* Deal with existing clients. */ /* Deal with existing clients. */
if (XQueryTree(X_Dpy, sc->rootwin, &w0, &w1, &wins, &nwins)) { if (XQueryTree(X_Dpy, sc->rootwin, &w0, &w1, &wins, &nwins)) {

View File

@@ -127,14 +127,8 @@ void
search_print_cmd(struct menu *mi, int i) search_print_cmd(struct menu *mi, int i)
{ {
struct cmd *cmd = (struct cmd *)mi->ctx; struct cmd *cmd = (struct cmd *)mi->ctx;
int special = 0;
if ((strcmp(cmd->name, "lock") == 0) || (void)snprintf(mi->print, sizeof(mi->print), "%s", cmd->name);
(strcmp(cmd->name, "term") == 0))
special = 1;
(void)snprintf(mi->print, sizeof(mi->print),
(special) ? "[%s]" : "%s", cmd->name);
} }
void void
@@ -162,7 +156,7 @@ search_print_client(struct menu *mi, int list)
cc->matchname = cc->name; cc->matchname = cc->name;
(void)snprintf(mi->print, sizeof(mi->print), "(%d) %c[%s] %s", (void)snprintf(mi->print, sizeof(mi->print), "(%d) %c[%s] %s",
(cc->group) ? cc->group->num : 0, flag, (cc->gc) ? cc->gc->num : 0, flag,
(cc->label) ? cc->label : "", cc->matchname); (cc->label) ? cc->label : "", cc->matchname);
} }

View File

@@ -77,7 +77,7 @@ xev_handle_maprequest(XEvent *ee)
XMapRequestEvent *e = &ee->xmaprequest; XMapRequestEvent *e = &ee->xmaprequest;
struct client_ctx *cc = NULL, *old_cc; struct client_ctx *cc = NULL, *old_cc;
if ((old_cc = client_current())) if ((old_cc = client_current()) != NULL)
client_ptrsave(old_cc); client_ptrsave(old_cc);
if ((cc = client_find(e->window)) == NULL) if ((cc = client_find(e->window)) == NULL)
@@ -252,7 +252,7 @@ xev_handle_buttonrelease(XEvent *ee)
{ {
struct client_ctx *cc; struct client_ctx *cc;
if ((cc = client_current())) if ((cc = client_current()) != NULL)
group_toggle_membership_leave(cc); group_toggle_membership_leave(cc);
} }
@@ -339,7 +339,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())) if ((old_cc = client_current()) != NULL)
client_ptrsave(old_cc); client_ptrsave(old_cc);
client_ptrwarp(cc); client_ptrwarp(cc);
} }

45
xutil.c
View File

@@ -228,6 +228,27 @@ xu_ewmh_net_client_list(struct screen_ctx *sc)
free(winlist); free(winlist);
} }
void
xu_ewmh_net_client_list_stacking(struct screen_ctx *sc)
{
struct client_ctx *cc;
Window *winlist;
int i = 0, j;
TAILQ_FOREACH(cc, &sc->clientq, entry)
i++;
if (i == 0)
return;
j = i;
winlist = xreallocarray(NULL, i, sizeof(*winlist));
TAILQ_FOREACH(cc, &sc->clientq, entry)
winlist[--j] = cc->win;
XChangeProperty(X_Dpy, sc->rootwin, ewmh[_NET_CLIENT_LIST_STACKING],
XA_WINDOW, 32, PropModeReplace, (unsigned char *)winlist, i);
free(winlist);
}
void void
xu_ewmh_net_active_window(struct screen_ctx *sc, Window w) xu_ewmh_net_active_window(struct screen_ctx *sc, Window w)
{ {
@@ -341,8 +362,8 @@ xu_ewmh_net_wm_desktop(struct client_ctx *cc)
{ {
long num = 0xffffffff; long num = 0xffffffff;
if (cc->group) if (cc->gc)
num = cc->group->num; num = cc->gc->num;
XChangeProperty(X_Dpy, cc->win, ewmh[_NET_WM_DESKTOP], XChangeProperty(X_Dpy, cc->win, ewmh[_NET_WM_DESKTOP],
XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&num, 1); XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&num, 1);
@@ -392,6 +413,9 @@ xu_ewmh_handle_net_wm_state_msg(struct client_ctx *cc, int action,
{ _NET_WM_STATE_DEMANDS_ATTENTION, { _NET_WM_STATE_DEMANDS_ATTENTION,
CLIENT_URGENCY, CLIENT_URGENCY,
client_urgency }, client_urgency },
{ _CWM_WM_STATE_FREEZE,
CLIENT_FREEZE,
client_toggle_freeze },
}; };
for (i = 0; i < nitems(handlers); i++) { for (i = 0; i < nitems(handlers); i++) {
@@ -423,16 +447,18 @@ xu_ewmh_restore_net_wm_state(struct client_ctx *cc)
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
if (atoms[i] == ewmh[_NET_WM_STATE_STICKY]) if (atoms[i] == ewmh[_NET_WM_STATE_STICKY])
client_toggle_sticky(cc); client_toggle_sticky(cc);
if (atoms[i] == ewmh[_NET_WM_STATE_MAXIMIZED_HORZ])
client_toggle_hmaximize(cc);
if (atoms[i] == ewmh[_NET_WM_STATE_MAXIMIZED_VERT]) if (atoms[i] == ewmh[_NET_WM_STATE_MAXIMIZED_VERT])
client_toggle_vmaximize(cc); client_toggle_vmaximize(cc);
if (atoms[i] == ewmh[_NET_WM_STATE_MAXIMIZED_HORZ])
client_toggle_hmaximize(cc);
if (atoms[i] == ewmh[_NET_WM_STATE_HIDDEN]) if (atoms[i] == ewmh[_NET_WM_STATE_HIDDEN])
client_toggle_hidden(cc); client_toggle_hidden(cc);
if (atoms[i] == ewmh[_NET_WM_STATE_FULLSCREEN]) if (atoms[i] == ewmh[_NET_WM_STATE_FULLSCREEN])
client_toggle_fullscreen(cc); client_toggle_fullscreen(cc);
if (atoms[i] == ewmh[_NET_WM_STATE_DEMANDS_ATTENTION]) if (atoms[i] == ewmh[_NET_WM_STATE_DEMANDS_ATTENTION])
client_urgency(cc); client_urgency(cc);
if (atoms[i] == ewmh[_CWM_WM_STATE_FREEZE])
client_toggle_freeze(cc);
} }
free(atoms); free(atoms);
} }
@@ -447,11 +473,12 @@ xu_ewmh_set_net_wm_state(struct client_ctx *cc)
atoms = xreallocarray(NULL, (n + _NET_WM_STATES_NITEMS), sizeof(Atom)); atoms = xreallocarray(NULL, (n + _NET_WM_STATES_NITEMS), sizeof(Atom));
for (i = j = 0; i < n; i++) { for (i = j = 0; i < n; i++) {
if (oatoms[i] != ewmh[_NET_WM_STATE_STICKY] && if (oatoms[i] != ewmh[_NET_WM_STATE_STICKY] &&
oatoms[i] != ewmh[_NET_WM_STATE_MAXIMIZED_HORZ] &&
oatoms[i] != ewmh[_NET_WM_STATE_MAXIMIZED_VERT] && oatoms[i] != ewmh[_NET_WM_STATE_MAXIMIZED_VERT] &&
oatoms[i] != ewmh[_NET_WM_STATE_MAXIMIZED_HORZ] &&
oatoms[i] != ewmh[_NET_WM_STATE_HIDDEN] && oatoms[i] != ewmh[_NET_WM_STATE_HIDDEN] &&
oatoms[i] != ewmh[_NET_WM_STATE_FULLSCREEN] && oatoms[i] != ewmh[_NET_WM_STATE_FULLSCREEN] &&
oatoms[i] != ewmh[_NET_WM_STATE_DEMANDS_ATTENTION]) oatoms[i] != ewmh[_NET_WM_STATE_DEMANDS_ATTENTION] &&
oatoms[i] != ewmh[_CWM_WM_STATE_FREEZE])
atoms[j++] = oatoms[i]; atoms[j++] = oatoms[i];
} }
free(oatoms); free(oatoms);
@@ -462,13 +489,15 @@ xu_ewmh_set_net_wm_state(struct client_ctx *cc)
if (cc->flags & CLIENT_FULLSCREEN) if (cc->flags & CLIENT_FULLSCREEN)
atoms[j++] = ewmh[_NET_WM_STATE_FULLSCREEN]; atoms[j++] = ewmh[_NET_WM_STATE_FULLSCREEN];
else { else {
if (cc->flags & CLIENT_HMAXIMIZED)
atoms[j++] = ewmh[_NET_WM_STATE_MAXIMIZED_HORZ];
if (cc->flags & CLIENT_VMAXIMIZED) if (cc->flags & CLIENT_VMAXIMIZED)
atoms[j++] = ewmh[_NET_WM_STATE_MAXIMIZED_VERT]; atoms[j++] = ewmh[_NET_WM_STATE_MAXIMIZED_VERT];
if (cc->flags & CLIENT_HMAXIMIZED)
atoms[j++] = ewmh[_NET_WM_STATE_MAXIMIZED_HORZ];
} }
if (cc->flags & CLIENT_URGENCY) if (cc->flags & CLIENT_URGENCY)
atoms[j++] = ewmh[_NET_WM_STATE_DEMANDS_ATTENTION]; atoms[j++] = ewmh[_NET_WM_STATE_DEMANDS_ATTENTION];
if (cc->flags & CLIENT_FREEZE)
atoms[j++] = ewmh[_CWM_WM_STATE_FREEZE];
if (j > 0) if (j > 0)
XChangeProperty(X_Dpy, cc->win, ewmh[_NET_WM_STATE], XChangeProperty(X_Dpy, cc->win, ewmh[_NET_WM_STATE],
XA_ATOM, 32, PropModeReplace, (unsigned char *)atoms, j); XA_ATOM, 32, PropModeReplace, (unsigned char *)atoms, j);