Implement _NET_WM_STATE_STICKY, bound to CM-s by default; allows any

client to 'stick' to all desktops (ewmh speak) or groups - this
currently has the same affect as setting a client's group to 'nogroup',
with the exception that the client can also be in a group, so when
un-sticking, the client will go back to its original group/desktop.
This commit is contained in:
okan 2014-08-25 12:49:19 +00:00
parent ed164794cb
commit 7314a3aefd
8 changed files with 47 additions and 3 deletions

View File

@ -180,6 +180,7 @@ struct client_ctx {
#define CLIENT_WM_TAKE_FOCUS 0x0200
#define CLIENT_URGENCY 0x0400
#define CLIENT_FULLSCREEN 0x0800
#define CLIENT_STICKY 0x1000
#define CLIENT_HIGHLIGHT (CLIENT_GROUP | CLIENT_UNGROUP)
#define CLIENT_MAXFLAGS (CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED)
@ -349,7 +350,8 @@ enum {
_NET_WM_DESKTOP,
_NET_CLOSE_WINDOW,
_NET_WM_STATE,
#define _NET_WM_STATES_NITEMS 4
#define _NET_WM_STATES_NITEMS 5
_NET_WM_STATE_STICKY,
_NET_WM_STATE_MAXIMIZED_VERT,
_NET_WM_STATE_MAXIMIZED_HORZ,
_NET_WM_STATE_FULLSCREEN,
@ -396,6 +398,7 @@ void client_set_wm_state(struct client_ctx *, long);
void client_setactive(struct client_ctx *);
void client_setname(struct client_ctx *);
int client_snapcalc(int, int, int, int, int);
void client_sticky(struct client_ctx *);
void client_transient(struct client_ctx *);
void client_unhide(struct client_ctx *);
void client_urgency(struct client_ctx *);
@ -464,6 +467,7 @@ void kbfunc_client_nogroup(struct client_ctx *,
void kbfunc_client_raise(struct client_ctx *, union arg *);
void kbfunc_client_rcycle(struct client_ctx *, union arg *);
void kbfunc_client_search(struct client_ctx *, union arg *);
void kbfunc_client_sticky(struct client_ctx *, union arg *);
void kbfunc_client_vmaximize(struct client_ctx *,
union arg *);
void kbfunc_cmdexec(struct client_ctx *, union arg *);

View File

@ -238,6 +238,17 @@ client_freeze(struct client_ctx *cc)
cc->flags |= CLIENT_FREEZE;
}
void
client_sticky(struct client_ctx *cc)
{
if (cc->flags & CLIENT_STICKY)
cc->flags &= ~CLIENT_STICKY;
else
cc->flags |= CLIENT_STICKY;
xu_ewmh_set_net_wm_state(cc);
}
void
client_fullscreen(struct client_ctx *cc)
{
@ -468,6 +479,9 @@ 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->active = 0;
@ -481,6 +495,9 @@ 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;

3
conf.c
View File

@ -204,6 +204,7 @@ static const struct {
{ "CM-g", "grouptoggle" },
{ "CM-f", "fullscreen" },
{ "CM-m", "maximize" },
{ "CM-s", "sticky" },
{ "CM-equal", "vmaximize" },
{ "CMS-equal", "hmaximize" },
{ "CMS-f", "freeze" },
@ -389,6 +390,7 @@ static const struct {
{ "rcycleingroup", kbfunc_client_cycle, CWM_WIN,
{.i = CWM_RCYCLE|CWM_INGROUP} },
{ "grouptoggle", kbfunc_client_grouptoggle, CWM_WIN, {0}},
{ "sticky", kbfunc_client_sticky, CWM_WIN, {0} },
{ "fullscreen", kbfunc_client_fullscreen, CWM_WIN, {0} },
{ "maximize", kbfunc_client_maximize, CWM_WIN, {0} },
{ "vmaximize", kbfunc_client_vmaximize, CWM_WIN, {0} },
@ -678,6 +680,7 @@ static char *ewmhints[] = {
"_NET_WM_DESKTOP",
"_NET_CLOSE_WINDOW",
"_NET_WM_STATE",
"_NET_WM_STATE_STICKY",
"_NET_WM_STATE_MAXIMIZED_VERT",
"_NET_WM_STATE_MAXIMIZED_HORZ",
"_NET_WM_STATE_FULLSCREEN",

4
cwm.1
View File

@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: December 16 2013 $
.Dd $Mdocdate$
.Dt CWM 1
.Os
.Sh NAME
@ -90,6 +90,8 @@ Cycle through active groups.
Reverse cycle through active groups.
.It Ic CMS-f
Toggle freezing geometry of current window.
.It Ic CM-s
Toggle stickiness of current window.
.It Ic CM-f
Toggle full-screen mode of current window.
.It Ic CM-m

View File

@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: December 16 2013 $
.Dd $Mdocdate$
.Dt CWMRC 5
.Os
.Sh NAME
@ -341,6 +341,8 @@ Raise current window.
Label current window.
.It freeze
Freeze current window geometry.
.It sticky
Stick current window to all groups (same as assigning to nogroup).
.It fullscreen
Full-screen current window (gap + border removed).
.It maximize

View File

@ -207,6 +207,8 @@ group_hidden_state(struct group_ctx *gc)
int hidden = 0, same = 0;
TAILQ_FOREACH(cc, &gc->clients, group_entry) {
if (cc->flags & CLIENT_STICKY)
continue;
if (hidden == ((cc->flags & CLIENT_HIDDEN) ? 1 : 0))
same++;
}

View File

@ -432,6 +432,12 @@ kbfunc_client_movetogroup(struct client_ctx *cc, union arg *arg)
group_movetogroup(cc, arg->i);
}
void
kbfunc_client_sticky(struct client_ctx *cc, union arg *arg)
{
client_sticky(cc);
}
void
kbfunc_client_fullscreen(struct client_ctx *cc, union arg *arg)
{

View File

@ -326,6 +326,9 @@ xu_ewmh_handle_net_wm_state_msg(struct client_ctx *cc, int action,
int property;
void (*toggle)(struct client_ctx *);
} handlers[] = {
{ _NET_WM_STATE_STICKY,
CLIENT_STICKY,
client_sticky },
{ _NET_WM_STATE_MAXIMIZED_VERT,
CLIENT_VMAXIMIZED,
client_vmaximize },
@ -367,6 +370,8 @@ xu_ewmh_restore_net_wm_state(struct client_ctx *cc)
atoms = xu_ewmh_get_net_wm_state(cc, &n);
for (i = 0; i < n; i++) {
if (atoms[i] == ewmh[_NET_WM_STATE_STICKY])
client_sticky(cc);
if (atoms[i] == ewmh[_NET_WM_STATE_MAXIMIZED_HORZ])
client_hmaximize(cc);
if (atoms[i] == ewmh[_NET_WM_STATE_MAXIMIZED_VERT])
@ -391,10 +396,13 @@ xu_ewmh_set_net_wm_state(struct client_ctx *cc)
if (oatoms[i] != ewmh[_NET_WM_STATE_MAXIMIZED_HORZ] &&
oatoms[i] != ewmh[_NET_WM_STATE_MAXIMIZED_VERT] &&
oatoms[i] != ewmh[_NET_WM_STATE_FULLSCREEN] &&
oatoms[i] != ewmh[_NET_WM_STATE_STICKY] &&
oatoms[i] != ewmh[_NET_WM_STATE_DEMANDS_ATTENTION])
atoms[j++] = oatoms[i];
}
free(oatoms);
if (cc->flags & CLIENT_STICKY)
atoms[j++] = ewmh[_NET_WM_STATE_STICKY];
if (cc->flags & CLIENT_FULLSCREEN)
atoms[j++] = ewmh[_NET_WM_STATE_FULLSCREEN];
else {