mirror of
https://github.com/leahneukirchen/cwm.git
synced 2023-08-10 21:13:12 +03:00
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:
commit
3f0b6cf4ea
23
calmwm.h
23
calmwm.h
@ -64,12 +64,12 @@ size_t strlcpy(char *, const char *, size_t);
|
||||
#define CONFFILE ".cwmrc"
|
||||
#define WMNAME "CWM"
|
||||
|
||||
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
|
||||
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
||||
#define MENUMASK (MOUSEMASK|ButtonMotionMask|ExposureMask)
|
||||
#define MENUGRABMASK (MOUSEMASK|ButtonMotionMask|StructureNotifyMask)
|
||||
#define KEYMASK (KeyPressMask|ExposureMask)
|
||||
#define IGNOREMODMASK (LockMask|Mod2Mask)
|
||||
#define BUTTONMASK (ButtonPressMask | ButtonReleaseMask)
|
||||
#define MOUSEMASK (BUTTONMASK | PointerMotionMask)
|
||||
#define MENUMASK (MOUSEMASK | ButtonMotionMask | ExposureMask)
|
||||
#define MENUGRABMASK (MOUSEMASK | ButtonMotionMask | StructureNotifyMask)
|
||||
#define KEYMASK (KeyPressMask | ExposureMask)
|
||||
#define IGNOREMODMASK (LockMask | Mod2Mask | 0x2000)
|
||||
|
||||
/* kb movement */
|
||||
#define CWM_MOVE 0x0001
|
||||
@ -168,6 +168,7 @@ struct client_ctx {
|
||||
TAILQ_ENTRY(client_ctx) entry;
|
||||
TAILQ_ENTRY(client_ctx) group_entry;
|
||||
struct screen_ctx *sc;
|
||||
struct group_ctx *gc;
|
||||
Window win;
|
||||
Colormap colormap;
|
||||
unsigned int bwidth; /* border width */
|
||||
@ -219,7 +220,6 @@ struct client_ctx {
|
||||
char *name;
|
||||
char *label;
|
||||
char *matchname;
|
||||
struct group_ctx *group;
|
||||
XClassHint ch;
|
||||
XWMHints *wmh;
|
||||
};
|
||||
@ -373,6 +373,7 @@ enum {
|
||||
_NET_SUPPORTING_WM_CHECK,
|
||||
_NET_ACTIVE_WINDOW,
|
||||
_NET_CLIENT_LIST,
|
||||
_NET_CLIENT_LIST_STACKING,
|
||||
_NET_NUMBER_OF_DESKTOPS,
|
||||
_NET_CURRENT_DESKTOP,
|
||||
_NET_DESKTOP_VIEWPORT,
|
||||
@ -385,13 +386,14 @@ enum {
|
||||
_NET_WM_DESKTOP,
|
||||
_NET_CLOSE_WINDOW,
|
||||
_NET_WM_STATE,
|
||||
#define _NET_WM_STATES_NITEMS 6
|
||||
#define _NET_WM_STATES_NITEMS 7
|
||||
_NET_WM_STATE_STICKY,
|
||||
_NET_WM_STATE_MAXIMIZED_VERT,
|
||||
_NET_WM_STATE_MAXIMIZED_HORZ,
|
||||
_NET_WM_STATE_HIDDEN,
|
||||
_NET_WM_STATE_FULLSCREEN,
|
||||
_NET_WM_STATE_DEMANDS_ATTENTION,
|
||||
_CWM_WM_STATE_FREEZE,
|
||||
EWMH_NITEMS
|
||||
};
|
||||
enum {
|
||||
@ -445,7 +447,8 @@ void client_warp(struct client_ctx *);
|
||||
void client_wm_hints(struct client_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_hide(struct group_ctx *);
|
||||
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_movetogroup(struct client_ctx *, int);
|
||||
void group_only(struct screen_ctx *, int);
|
||||
int group_restore(struct client_ctx *);
|
||||
void group_show(struct group_ctx *);
|
||||
void group_toggle_membership_enter(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_workarea(struct screen_ctx *);
|
||||
void xu_ewmh_net_client_list(struct screen_ctx *);
|
||||
void xu_ewmh_net_client_list_stacking(struct screen_ctx *);
|
||||
void xu_ewmh_net_active_window(struct screen_ctx *, Window);
|
||||
void xu_ewmh_net_wm_desktop_viewport(struct screen_ctx *);
|
||||
void xu_ewmh_net_wm_number_of_desktops(struct screen_ctx *);
|
||||
|
84
client.c
84
client.c
@ -112,6 +112,7 @@ client_init(Window win, struct screen_ctx *sc)
|
||||
TAILQ_INSERT_TAIL(&sc->clientq, cc, entry);
|
||||
|
||||
xu_ewmh_net_client_list(sc);
|
||||
xu_ewmh_net_client_list_stacking(sc);
|
||||
xu_ewmh_restore_net_wm_state(cc);
|
||||
|
||||
if (client_get_wm_state(cc) == IconicState)
|
||||
@ -119,9 +120,17 @@ client_init(Window win, struct screen_ctx *sc)
|
||||
else
|
||||
client_unhide(cc);
|
||||
|
||||
if (mapped)
|
||||
group_autogroup(cc);
|
||||
|
||||
if (mapped) {
|
||||
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);
|
||||
XUngrabServer(X_Dpy);
|
||||
|
||||
@ -152,9 +161,10 @@ client_delete(struct client_ctx *cc)
|
||||
TAILQ_REMOVE(&sc->clientq, cc, entry);
|
||||
|
||||
xu_ewmh_net_client_list(sc);
|
||||
xu_ewmh_net_client_list_stacking(sc);
|
||||
|
||||
if (cc->group != NULL)
|
||||
TAILQ_REMOVE(&cc->group->clientq, cc, group_entry);
|
||||
if (cc->gc != NULL)
|
||||
TAILQ_REMOVE(&cc->gc->clientq, cc, group_entry);
|
||||
|
||||
if (cc == client_current())
|
||||
client_none(sc);
|
||||
@ -194,7 +204,7 @@ client_setactive(struct client_ctx *cc)
|
||||
if (cc->flags & CLIENT_WM_TAKE_FOCUS)
|
||||
client_msg(cc, cwmh[WM_TAKE_FOCUS], Last_Event_Time);
|
||||
|
||||
if ((oldcc = client_current())) {
|
||||
if ((oldcc = client_current()) != NULL) {
|
||||
oldcc->flags &= ~CLIENT_ACTIVE;
|
||||
client_draw_border(oldcc);
|
||||
}
|
||||
@ -233,10 +243,15 @@ client_current(void)
|
||||
void
|
||||
client_toggle_freeze(struct client_ctx *cc)
|
||||
{
|
||||
if (cc->flags & CLIENT_FULLSCREEN)
|
||||
return;
|
||||
|
||||
if (cc->flags & CLIENT_FREEZE)
|
||||
cc->flags &= ~CLIENT_FREEZE;
|
||||
else
|
||||
cc->flags |= CLIENT_FREEZE;
|
||||
|
||||
xu_ewmh_set_net_wm_state(cc);
|
||||
}
|
||||
|
||||
void
|
||||
@ -299,7 +314,7 @@ client_toggle_maximize(struct client_ctx *cc)
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
struct geom area;
|
||||
|
||||
if (cc->flags & (CLIENT_FREEZE|CLIENT_STICKY))
|
||||
if (cc->flags & CLIENT_FREEZE)
|
||||
return;
|
||||
|
||||
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 geom area;
|
||||
|
||||
if (cc->flags & (CLIENT_FREEZE|CLIENT_STICKY))
|
||||
if (cc->flags & CLIENT_FREEZE)
|
||||
return;
|
||||
|
||||
if (cc->flags & CLIENT_VMAXIMIZED) {
|
||||
@ -376,7 +391,7 @@ client_toggle_hmaximize(struct client_ctx *cc)
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
struct geom area;
|
||||
|
||||
if (cc->flags & (CLIENT_FREEZE|CLIENT_STICKY))
|
||||
if (cc->flags & CLIENT_FREEZE)
|
||||
return;
|
||||
|
||||
if (cc->flags & CLIENT_HMAXIMIZED) {
|
||||
@ -491,9 +506,6 @@ client_ptrsave(struct client_ctx *cc)
|
||||
void
|
||||
client_hide(struct client_ctx *cc)
|
||||
{
|
||||
if (cc->flags & CLIENT_STICKY)
|
||||
return;
|
||||
|
||||
XUnmapWindow(X_Dpy, cc->win);
|
||||
|
||||
cc->flags &= ~CLIENT_ACTIVE;
|
||||
@ -507,9 +519,6 @@ client_hide(struct client_ctx *cc)
|
||||
void
|
||||
client_unhide(struct client_ctx *cc)
|
||||
{
|
||||
if (cc->flags & CLIENT_STICKY)
|
||||
return;
|
||||
|
||||
XMapRaised(X_Dpy, cc->win);
|
||||
|
||||
cc->flags &= ~CLIENT_HIDDEN;
|
||||
@ -647,29 +656,33 @@ match:
|
||||
void
|
||||
client_cycle(struct screen_ctx *sc, int flags)
|
||||
{
|
||||
struct client_ctx *oldcc, *newcc;
|
||||
struct client_ctx *newcc, *oldcc;
|
||||
int again = 1;
|
||||
|
||||
/* For X apps that ignore events. */
|
||||
XGrabKeyboard(X_Dpy, sc->rootwin, True,
|
||||
GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
|
||||
if (TAILQ_EMPTY(&sc->clientq))
|
||||
return;
|
||||
|
||||
oldcc = client_current();
|
||||
if (oldcc == NULL)
|
||||
oldcc = ((flags & CWM_RCYCLE) ?
|
||||
oldcc = (flags & CWM_RCYCLE) ?
|
||||
TAILQ_LAST(&sc->clientq, client_ctx_q) :
|
||||
TAILQ_FIRST(&sc->clientq));
|
||||
TAILQ_FIRST(&sc->clientq);
|
||||
|
||||
newcc = oldcc;
|
||||
while (again) {
|
||||
again = 0;
|
||||
|
||||
newcc = ((flags & CWM_RCYCLE) ? client_prev(newcc) :
|
||||
client_next(newcc));
|
||||
newcc = (flags & CWM_RCYCLE) ? client_prev(newcc) :
|
||||
client_next(newcc);
|
||||
|
||||
/* Only cycle visible and non-ignored windows. */
|
||||
if ((newcc->flags & (CLIENT_HIDDEN|CLIENT_IGNORE))
|
||||
if ((newcc->flags & (CLIENT_HIDDEN | CLIENT_IGNORE))
|
||||
|| ((flags & CWM_INGROUP) &&
|
||||
(newcc->group != oldcc->group)))
|
||||
(newcc->gc != oldcc->gc)))
|
||||
again = 1;
|
||||
|
||||
/* Is oldcc the only non-hidden window? */
|
||||
@ -694,9 +707,10 @@ client_cycle_leave(struct screen_ctx *sc)
|
||||
|
||||
sc->cycling = 0;
|
||||
|
||||
if ((cc = client_current())) {
|
||||
if ((cc = client_current()) != NULL) {
|
||||
client_mtf(cc);
|
||||
group_toggle_membership_leave(cc);
|
||||
cc->flags &= ~CLIENT_HIGHLIGHT;
|
||||
client_draw_border(cc);
|
||||
XUngrabKeyboard(X_Dpy, CurrentTime);
|
||||
}
|
||||
}
|
||||
@ -705,20 +719,20 @@ static struct client_ctx *
|
||||
client_next(struct client_ctx *cc)
|
||||
{
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
struct client_ctx *ccc;
|
||||
struct client_ctx *newcc;
|
||||
|
||||
return(((ccc = TAILQ_NEXT(cc, entry)) != NULL) ?
|
||||
ccc : TAILQ_FIRST(&sc->clientq));
|
||||
return(((newcc = TAILQ_NEXT(cc, entry)) != NULL) ?
|
||||
newcc : TAILQ_FIRST(&sc->clientq));
|
||||
}
|
||||
|
||||
static struct client_ctx *
|
||||
client_prev(struct client_ctx *cc)
|
||||
{
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
struct client_ctx *ccc;
|
||||
struct client_ctx *newcc;
|
||||
|
||||
return(((ccc = TAILQ_PREV(cc, client_ctx_q, entry)) != NULL) ?
|
||||
ccc : TAILQ_LAST(&sc->clientq, client_ctx_q));
|
||||
return(((newcc = TAILQ_PREV(cc, client_ctx_q, entry)) != NULL) ?
|
||||
newcc : TAILQ_LAST(&sc->clientq, client_ctx_q));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -727,7 +741,7 @@ client_placecalc(struct client_ctx *cc)
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
int xslack, yslack;
|
||||
|
||||
if (cc->hint.flags & (USPosition|PPosition)) {
|
||||
if (cc->hint.flags & (USPosition | PPosition)) {
|
||||
/*
|
||||
* Ignore XINERAMA screens, just make sure it's somewhere
|
||||
* in the virtual desktop. else it stops people putting xterms
|
||||
@ -901,8 +915,8 @@ client_transient(struct client_ctx *cc)
|
||||
Window trans;
|
||||
|
||||
if (XGetTransientForHint(X_Dpy, cc->win, &trans)) {
|
||||
if ((tc = client_find(trans)) && tc->group) {
|
||||
group_movetogroup(cc, tc->group->num);
|
||||
if ((tc = client_find(trans)) != NULL && tc->gc) {
|
||||
group_movetogroup(cc, tc->gc->num);
|
||||
if (tc->flags & CLIENT_IGNORE)
|
||||
cc->flags |= CLIENT_IGNORE;
|
||||
}
|
||||
@ -947,7 +961,7 @@ void
|
||||
client_htile(struct client_ctx *cc)
|
||||
{
|
||||
struct client_ctx *ci;
|
||||
struct group_ctx *gc = cc->group;
|
||||
struct group_ctx *gc = cc->gc;
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
struct geom area;
|
||||
int i, n, mh, x, h, w;
|
||||
@ -1006,7 +1020,7 @@ void
|
||||
client_vtile(struct client_ctx *cc)
|
||||
{
|
||||
struct client_ctx *ci;
|
||||
struct group_ctx *gc = cc->group;
|
||||
struct group_ctx *gc = cc->gc;
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
struct geom area;
|
||||
int i, n, mw, y, h, w;
|
||||
|
79
conf.c
79
conf.c
@ -40,7 +40,7 @@ static void conf_unbind_mouse(struct conf *, struct binding *);
|
||||
int
|
||||
conf_cmd_add(struct conf *c, const char *name, const char *path)
|
||||
{
|
||||
struct cmd *cmd, *prev;
|
||||
struct cmd *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);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
@ -224,18 +217,18 @@ static const struct {
|
||||
{ "M-j", "movedown" },
|
||||
{ "M-k", "moveup" },
|
||||
{ "M-l", "moveright" },
|
||||
{ "M-H", "bigmoveleft" },
|
||||
{ "M-J", "bigmovedown" },
|
||||
{ "M-K", "bigmoveup" },
|
||||
{ "M-L", "bigmoveright" },
|
||||
{ "MS-h", "bigmoveleft" },
|
||||
{ "MS-j", "bigmovedown" },
|
||||
{ "MS-k", "bigmoveup" },
|
||||
{ "MS-l", "bigmoveright" },
|
||||
{ "CM-h", "resizeleft" },
|
||||
{ "CM-j", "resizedown" },
|
||||
{ "CM-k", "resizeup" },
|
||||
{ "CM-l", "resizeright" },
|
||||
{ "CM-H", "bigresizeleft" },
|
||||
{ "CM-J", "bigresizedown" },
|
||||
{ "CM-K", "bigresizeup" },
|
||||
{ "CM-L", "bigresizeright" },
|
||||
{ "CMS-h", "bigresizeleft" },
|
||||
{ "CMS-j", "bigresizedown" },
|
||||
{ "CMS-k", "bigresizeup" },
|
||||
{ "CMS-l", "bigresizeright" },
|
||||
{ "C-Left", "ptrmoveleft" },
|
||||
{ "C-Down", "ptrmovedown" },
|
||||
{ "C-Up", "ptrmoveup" },
|
||||
@ -397,9 +390,9 @@ static const struct {
|
||||
{ "cyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_CYCLE} },
|
||||
{ "rcyclegroup", kbfunc_client_cyclegroup, 0, {.i = CWM_RCYCLE} },
|
||||
{ "cycleingroup", kbfunc_client_cycle, CWM_WIN,
|
||||
{.i = CWM_CYCLE|CWM_INGROUP} },
|
||||
{.i = (CWM_CYCLE | CWM_INGROUP)} },
|
||||
{ "rcycleingroup", kbfunc_client_cycle, CWM_WIN,
|
||||
{.i = CWM_RCYCLE|CWM_INGROUP} },
|
||||
{.i = (CWM_RCYCLE | CWM_INGROUP)} },
|
||||
{ "grouptoggle", kbfunc_client_grouptoggle, CWM_WIN, {.i = 0}},
|
||||
{ "sticky", kbfunc_client_toggle_sticky, CWM_WIN, {0} },
|
||||
{ "fullscreen", kbfunc_client_toggle_fullscreen, CWM_WIN, {0} },
|
||||
@ -415,53 +408,53 @@ static const struct {
|
||||
{ "terminal", kbfunc_term, 0, {0} },
|
||||
{ "lock", kbfunc_lock, 0, {0} },
|
||||
{ "moveup", kbfunc_client_moveresize, CWM_WIN,
|
||||
{.i = (CWM_UP|CWM_MOVE)} },
|
||||
{.i = (CWM_UP | CWM_MOVE)} },
|
||||
{ "movedown", kbfunc_client_moveresize, CWM_WIN,
|
||||
{.i = (CWM_DOWN|CWM_MOVE)} },
|
||||
{.i = (CWM_DOWN | CWM_MOVE)} },
|
||||
{ "moveright", kbfunc_client_moveresize, CWM_WIN,
|
||||
{.i = (CWM_RIGHT|CWM_MOVE)} },
|
||||
{.i = (CWM_RIGHT | CWM_MOVE)} },
|
||||
{ "moveleft", kbfunc_client_moveresize, CWM_WIN,
|
||||
{.i = (CWM_LEFT|CWM_MOVE)} },
|
||||
{.i = (CWM_LEFT | CWM_MOVE)} },
|
||||
{ "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,
|
||||
{.i = (CWM_DOWN|CWM_MOVE|CWM_BIGMOVE)} },
|
||||
{.i = (CWM_DOWN | CWM_MOVE | CWM_BIGMOVE)} },
|
||||
{ "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,
|
||||
{.i = (CWM_LEFT|CWM_MOVE|CWM_BIGMOVE)} },
|
||||
{.i = (CWM_LEFT | CWM_MOVE | CWM_BIGMOVE)} },
|
||||
{ "resizeup", kbfunc_client_moveresize, CWM_WIN,
|
||||
{.i = (CWM_UP|CWM_RESIZE)} },
|
||||
{.i = (CWM_UP | CWM_RESIZE)} },
|
||||
{ "resizedown", kbfunc_client_moveresize, CWM_WIN,
|
||||
{.i = (CWM_DOWN|CWM_RESIZE)} },
|
||||
{.i = (CWM_DOWN | CWM_RESIZE)} },
|
||||
{ "resizeright", kbfunc_client_moveresize, CWM_WIN,
|
||||
{.i = (CWM_RIGHT|CWM_RESIZE)} },
|
||||
{.i = (CWM_RIGHT | CWM_RESIZE)} },
|
||||
{ "resizeleft", kbfunc_client_moveresize, CWM_WIN,
|
||||
{.i = (CWM_LEFT|CWM_RESIZE)} },
|
||||
{.i = (CWM_LEFT | CWM_RESIZE)} },
|
||||
{ "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,
|
||||
{.i = (CWM_DOWN|CWM_RESIZE|CWM_BIGMOVE)} },
|
||||
{.i = (CWM_DOWN | CWM_RESIZE | CWM_BIGMOVE)} },
|
||||
{ "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,
|
||||
{.i = (CWM_LEFT|CWM_RESIZE|CWM_BIGMOVE)} },
|
||||
{.i = (CWM_LEFT | CWM_RESIZE | CWM_BIGMOVE)} },
|
||||
{ "ptrmoveup", kbfunc_client_moveresize, 0,
|
||||
{.i = (CWM_UP|CWM_PTRMOVE)} },
|
||||
{.i = (CWM_UP | CWM_PTRMOVE)} },
|
||||
{ "ptrmovedown", kbfunc_client_moveresize, 0,
|
||||
{.i = (CWM_DOWN|CWM_PTRMOVE)} },
|
||||
{.i = (CWM_DOWN | CWM_PTRMOVE)} },
|
||||
{ "ptrmoveleft", kbfunc_client_moveresize, 0,
|
||||
{.i = (CWM_LEFT|CWM_PTRMOVE)} },
|
||||
{.i = (CWM_LEFT | CWM_PTRMOVE)} },
|
||||
{ "ptrmoveright", kbfunc_client_moveresize, 0,
|
||||
{.i = (CWM_RIGHT|CWM_PTRMOVE)} },
|
||||
{.i = (CWM_RIGHT | CWM_PTRMOVE)} },
|
||||
{ "bigptrmoveup", kbfunc_client_moveresize, 0,
|
||||
{.i = (CWM_UP|CWM_PTRMOVE|CWM_BIGMOVE)} },
|
||||
{.i = (CWM_UP | CWM_PTRMOVE | CWM_BIGMOVE)} },
|
||||
{ "bigptrmovedown", kbfunc_client_moveresize, 0,
|
||||
{.i = (CWM_DOWN|CWM_PTRMOVE|CWM_BIGMOVE)} },
|
||||
{.i = (CWM_DOWN | CWM_PTRMOVE | CWM_BIGMOVE)} },
|
||||
{ "bigptrmoveleft", kbfunc_client_moveresize, 0,
|
||||
{.i = (CWM_LEFT|CWM_PTRMOVE|CWM_BIGMOVE)} },
|
||||
{.i = (CWM_LEFT | CWM_PTRMOVE | CWM_BIGMOVE)} },
|
||||
{ "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} },
|
||||
{ "vtile", kbfunc_tile, CWM_WIN, {.i = CWM_TILE_VERT} },
|
||||
{ "window_lower", kbfunc_client_lower, CWM_WIN, {0} },
|
||||
@ -675,6 +668,7 @@ static char *ewmhints[] = {
|
||||
"_NET_SUPPORTING_WM_CHECK",
|
||||
"_NET_ACTIVE_WINDOW",
|
||||
"_NET_CLIENT_LIST",
|
||||
"_NET_CLIENT_LIST_STACKING",
|
||||
"_NET_NUMBER_OF_DESKTOPS",
|
||||
"_NET_CURRENT_DESKTOP",
|
||||
"_NET_DESKTOP_VIEWPORT",
|
||||
@ -693,6 +687,7 @@ static char *ewmhints[] = {
|
||||
"_NET_WM_STATE_HIDDEN",
|
||||
"_NET_WM_STATE_FULLSCREEN",
|
||||
"_NET_WM_STATE_DEMANDS_ATTENTION",
|
||||
"_CWM_WM_STATE_FREEZE",
|
||||
};
|
||||
|
||||
void
|
||||
|
4
cwm.1
4
cwm.1
@ -117,9 +117,9 @@ Toggle maximization of current window.
|
||||
Toggle vertical maximization of current window.
|
||||
.It Ic CMS-=
|
||||
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.
|
||||
.It Ic CS-[Up|Down|Left|Right]
|
||||
.It Ic CS-[Up | Down | Left | Right]
|
||||
Move pointer by a large amount; see
|
||||
.Xr cwmrc 5 .
|
||||
.It Ic M-[hjkl]
|
||||
|
150
group.c
150
group.c
@ -32,7 +32,8 @@
|
||||
|
||||
#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_setactive(struct group_ctx *);
|
||||
|
||||
@ -41,15 +42,18 @@ const char *num_to_name[] = {
|
||||
"seven", "eight", "nine"
|
||||
};
|
||||
|
||||
static void
|
||||
void
|
||||
group_assign(struct group_ctx *gc, struct client_ctx *cc)
|
||||
{
|
||||
if (cc->group != NULL)
|
||||
TAILQ_REMOVE(&cc->group->clientq, cc, group_entry);
|
||||
if (cc->gc != NULL)
|
||||
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);
|
||||
|
||||
xu_ewmh_net_wm_desktop(cc);
|
||||
@ -62,8 +66,10 @@ group_hide(struct group_ctx *gc)
|
||||
|
||||
screen_updatestackingorder(gc->sc);
|
||||
|
||||
TAILQ_FOREACH(cc, &gc->clientq, group_entry)
|
||||
client_hide(cc);
|
||||
TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
|
||||
if (!(cc->flags & CLIENT_STICKY))
|
||||
client_hide(cc);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -71,8 +77,10 @@ group_show(struct group_ctx *gc)
|
||||
{
|
||||
struct client_ctx *cc;
|
||||
|
||||
TAILQ_FOREACH(cc, &gc->clientq, group_entry)
|
||||
client_unhide(cc);
|
||||
TAILQ_FOREACH(cc, &gc->clientq, group_entry) {
|
||||
if (!(cc->flags & CLIENT_STICKY))
|
||||
client_unhide(cc);
|
||||
}
|
||||
|
||||
group_restack(gc);
|
||||
group_setactive(gc);
|
||||
@ -154,7 +162,7 @@ group_movetogroup(struct client_ctx *cc, int idx)
|
||||
break;
|
||||
}
|
||||
|
||||
if (cc->group == gc)
|
||||
if (cc->gc == gc)
|
||||
return;
|
||||
if (group_holds_only_hidden(gc))
|
||||
client_hide(cc);
|
||||
@ -167,7 +175,7 @@ group_toggle_membership_enter(struct client_ctx *cc)
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
struct group_ctx *gc = sc->group_active;
|
||||
|
||||
if (gc == cc->group) {
|
||||
if (gc == cc->gc) {
|
||||
group_assign(NULL, cc);
|
||||
cc->flags |= CLIENT_UNGROUP;
|
||||
} 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
|
||||
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)
|
||||
errx(1, "group_cycle: no active group");
|
||||
oldgc = sc->group_active;
|
||||
|
||||
newgc = oldgc;
|
||||
for (;;) {
|
||||
gc = (flags & CWM_RCYCLE) ? TAILQ_PREV(gc, group_ctx_q,
|
||||
entry) : TAILQ_NEXT(gc, entry);
|
||||
if (gc == NULL)
|
||||
gc = (flags & CWM_RCYCLE) ? TAILQ_LAST(&sc->groupq,
|
||||
group_ctx_q) : TAILQ_FIRST(&sc->groupq);
|
||||
if (gc == sc->group_active)
|
||||
newgc = (flags & CWM_RCYCLE) ? group_prev(newgc) :
|
||||
group_next(newgc);
|
||||
|
||||
if (newgc == oldgc)
|
||||
break;
|
||||
|
||||
if (!group_holds_only_sticky(gc) && showgroup == NULL)
|
||||
showgroup = gc;
|
||||
else if (!group_holds_only_hidden(gc))
|
||||
group_hide(gc);
|
||||
if (!group_holds_only_sticky(newgc) && showgroup == NULL)
|
||||
showgroup = newgc;
|
||||
else if (!group_holds_only_hidden(newgc))
|
||||
group_hide(newgc);
|
||||
}
|
||||
|
||||
if (showgroup == NULL)
|
||||
return;
|
||||
|
||||
group_hide(sc->group_active);
|
||||
group_hide(oldgc);
|
||||
|
||||
if (group_holds_only_hidden(showgroup))
|
||||
group_show(showgroup);
|
||||
@ -292,6 +295,26 @@ group_cycle(struct screen_ctx *sc, int flags)
|
||||
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
|
||||
group_alltoggle(struct screen_ctx *sc)
|
||||
{
|
||||
@ -306,51 +329,58 @@ group_alltoggle(struct screen_ctx *sc)
|
||||
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)
|
||||
{
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
struct autogroupwin *aw;
|
||||
struct group_ctx *gc;
|
||||
int num = -2, both_match = 0;
|
||||
long *grpnum;
|
||||
int num = -1, both_match = 0;
|
||||
|
||||
if (cc->ch.res_class == NULL || cc->ch.res_name == NULL)
|
||||
return;
|
||||
return(0);
|
||||
|
||||
if (xu_getprop(cc->win, ewmh[_NET_WM_DESKTOP],
|
||||
XA_CARDINAL, 1, (unsigned char **)&grpnum) > 0) {
|
||||
num = *grpnum;
|
||||
if (num > CALMWM_NGROUPS || num < -1)
|
||||
num = CALMWM_NGROUPS - 1;
|
||||
XFree(grpnum);
|
||||
} else {
|
||||
TAILQ_FOREACH(aw, &Conf.autogroupq, entry) {
|
||||
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;
|
||||
}
|
||||
TAILQ_FOREACH(aw, &Conf.autogroupq, entry) {
|
||||
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) {
|
||||
if (gc->num == num) {
|
||||
group_assign(gc, cc);
|
||||
return;
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (Conf.flags & CONF_STICKY_GROUPS)
|
||||
group_assign(sc->group_active, cc);
|
||||
else
|
||||
group_assign(NULL, cc);
|
||||
return(0);
|
||||
}
|
||||
|
19
kbfunc.c
19
kbfunc.c
@ -61,7 +61,7 @@ kbfunc_client_moveresize(struct client_ctx *cc, union arg *arg)
|
||||
int x, y, flags, amt;
|
||||
unsigned int mx, my;
|
||||
|
||||
if (cc->flags & (CLIENT_FREEZE|CLIENT_STICKY))
|
||||
if (cc->flags & CLIENT_FREEZE)
|
||||
return;
|
||||
|
||||
mx = my = 0;
|
||||
@ -177,8 +177,13 @@ kbfunc_menu_cmd(struct client_ctx *cc, union arg *arg)
|
||||
struct menu_q 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);
|
||||
}
|
||||
|
||||
if ((mi = menu_filter(sc, &menuq, "application", NULL, 0,
|
||||
search_match_text, search_print_cmd)) != NULL)
|
||||
@ -215,13 +220,7 @@ kbfunc_menu_group(struct client_ctx *cc, union arg *arg)
|
||||
void
|
||||
kbfunc_client_cycle(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
|
||||
/* XXX for X apps that ignore events */
|
||||
XGrabKeyboard(X_Dpy, sc->rootwin, True,
|
||||
GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
|
||||
client_cycle(sc, arg->i);
|
||||
client_cycle(cc->sc, arg->i);
|
||||
}
|
||||
|
||||
void
|
||||
@ -466,7 +465,7 @@ void
|
||||
kbfunc_client_grouptoggle(struct client_ctx *cc, union arg *arg)
|
||||
{
|
||||
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,
|
||||
GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
}
|
||||
|
10
mousefunc.c
10
mousefunc.c
@ -72,7 +72,7 @@ mousefunc_client_resize(struct client_ctx *cc, union arg *arg)
|
||||
struct screen_ctx *sc = cc->sc;
|
||||
int x = cc->geom.x, y = cc->geom.y;
|
||||
|
||||
if (cc->flags & (CLIENT_FREEZE|CLIENT_STICKY))
|
||||
if (cc->flags & CLIENT_FREEZE)
|
||||
return;
|
||||
|
||||
client_raise(cc);
|
||||
@ -128,7 +128,7 @@ mousefunc_client_move(struct client_ctx *cc, union arg *arg)
|
||||
|
||||
client_raise(cc);
|
||||
|
||||
if (cc->flags & (CLIENT_FREEZE|CLIENT_STICKY))
|
||||
if (cc->flags & CLIENT_FREEZE)
|
||||
return;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if ((mi = menu_filter(sc, &menuq, NULL, NULL, CWM_MENU_LIST,
|
||||
NULL, search_print_cmd)) != NULL)
|
||||
|
8
screen.c
8
screen.c
@ -67,12 +67,12 @@ screen_init(int which)
|
||||
xu_ewmh_net_virtual_roots(sc);
|
||||
|
||||
rootattr.cursor = Conf.cursor[CF_NORMAL];
|
||||
rootattr.event_mask = SubstructureRedirectMask|SubstructureNotifyMask|
|
||||
PropertyChangeMask|EnterWindowMask|LeaveWindowMask|
|
||||
ColormapChangeMask|BUTTONMASK;
|
||||
rootattr.event_mask = SubstructureRedirectMask |
|
||||
SubstructureNotifyMask | PropertyChangeMask | EnterWindowMask |
|
||||
LeaveWindowMask | ColormapChangeMask | BUTTONMASK;
|
||||
|
||||
XChangeWindowAttributes(X_Dpy, sc->rootwin,
|
||||
CWEventMask|CWCursor, &rootattr);
|
||||
(CWEventMask | CWCursor), &rootattr);
|
||||
|
||||
/* Deal with existing clients. */
|
||||
if (XQueryTree(X_Dpy, sc->rootwin, &w0, &w1, &wins, &nwins)) {
|
||||
|
10
search.c
10
search.c
@ -127,14 +127,8 @@ void
|
||||
search_print_cmd(struct menu *mi, int i)
|
||||
{
|
||||
struct cmd *cmd = (struct cmd *)mi->ctx;
|
||||
int special = 0;
|
||||
|
||||
if ((strcmp(cmd->name, "lock") == 0) ||
|
||||
(strcmp(cmd->name, "term") == 0))
|
||||
special = 1;
|
||||
|
||||
(void)snprintf(mi->print, sizeof(mi->print),
|
||||
(special) ? "[%s]" : "%s", cmd->name);
|
||||
(void)snprintf(mi->print, sizeof(mi->print), "%s", cmd->name);
|
||||
}
|
||||
|
||||
void
|
||||
@ -162,7 +156,7 @@ search_print_client(struct menu *mi, int list)
|
||||
cc->matchname = cc->name;
|
||||
|
||||
(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);
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ xev_handle_maprequest(XEvent *ee)
|
||||
XMapRequestEvent *e = &ee->xmaprequest;
|
||||
struct client_ctx *cc = NULL, *old_cc;
|
||||
|
||||
if ((old_cc = client_current()))
|
||||
if ((old_cc = client_current()) != NULL)
|
||||
client_ptrsave(old_cc);
|
||||
|
||||
if ((cc = client_find(e->window)) == NULL)
|
||||
@ -252,7 +252,7 @@ xev_handle_buttonrelease(XEvent *ee)
|
||||
{
|
||||
struct client_ctx *cc;
|
||||
|
||||
if ((cc = client_current()))
|
||||
if ((cc = client_current()) != NULL)
|
||||
group_toggle_membership_leave(cc);
|
||||
}
|
||||
|
||||
@ -339,7 +339,7 @@ xev_handle_clientmessage(XEvent *ee)
|
||||
}
|
||||
} else if (e->message_type == ewmh[_NET_ACTIVE_WINDOW]) {
|
||||
if ((cc = client_find(e->window)) != NULL) {
|
||||
if ((old_cc = client_current()))
|
||||
if ((old_cc = client_current()) != NULL)
|
||||
client_ptrsave(old_cc);
|
||||
client_ptrwarp(cc);
|
||||
}
|
||||
|
45
xutil.c
45
xutil.c
@ -228,6 +228,27 @@ xu_ewmh_net_client_list(struct screen_ctx *sc)
|
||||
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
|
||||
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;
|
||||
|
||||
if (cc->group)
|
||||
num = cc->group->num;
|
||||
if (cc->gc)
|
||||
num = cc->gc->num;
|
||||
|
||||
XChangeProperty(X_Dpy, cc->win, ewmh[_NET_WM_DESKTOP],
|
||||
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,
|
||||
CLIENT_URGENCY,
|
||||
client_urgency },
|
||||
{ _CWM_WM_STATE_FREEZE,
|
||||
CLIENT_FREEZE,
|
||||
client_toggle_freeze },
|
||||
};
|
||||
|
||||
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++) {
|
||||
if (atoms[i] == ewmh[_NET_WM_STATE_STICKY])
|
||||
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])
|
||||
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])
|
||||
client_toggle_hidden(cc);
|
||||
if (atoms[i] == ewmh[_NET_WM_STATE_FULLSCREEN])
|
||||
client_toggle_fullscreen(cc);
|
||||
if (atoms[i] == ewmh[_NET_WM_STATE_DEMANDS_ATTENTION])
|
||||
client_urgency(cc);
|
||||
if (atoms[i] == ewmh[_CWM_WM_STATE_FREEZE])
|
||||
client_toggle_freeze(cc);
|
||||
}
|
||||
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));
|
||||
for (i = j = 0; i < n; i++) {
|
||||
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_HORZ] &&
|
||||
oatoms[i] != ewmh[_NET_WM_STATE_HIDDEN] &&
|
||||
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];
|
||||
}
|
||||
free(oatoms);
|
||||
@ -462,13 +489,15 @@ xu_ewmh_set_net_wm_state(struct client_ctx *cc)
|
||||
if (cc->flags & CLIENT_FULLSCREEN)
|
||||
atoms[j++] = ewmh[_NET_WM_STATE_FULLSCREEN];
|
||||
else {
|
||||
if (cc->flags & CLIENT_HMAXIMIZED)
|
||||
atoms[j++] = ewmh[_NET_WM_STATE_MAXIMIZED_HORZ];
|
||||
if (cc->flags & CLIENT_VMAXIMIZED)
|
||||
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)
|
||||
atoms[j++] = ewmh[_NET_WM_STATE_DEMANDS_ATTENTION];
|
||||
if (cc->flags & CLIENT_FREEZE)
|
||||
atoms[j++] = ewmh[_CWM_WM_STATE_FREEZE];
|
||||
if (j > 0)
|
||||
XChangeProperty(X_Dpy, cc->win, ewmh[_NET_WM_STATE],
|
||||
XA_ATOM, 32, PropModeReplace, (unsigned char *)atoms, j);
|
||||
|
Loading…
Reference in New Issue
Block a user