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_WM_TAKE_FOCUS 0x0200
#define CLIENT_URGENCY 0x0400 #define CLIENT_URGENCY 0x0400
#define CLIENT_FULLSCREEN 0x0800 #define CLIENT_FULLSCREEN 0x0800
#define CLIENT_STICKY 0x1000
#define CLIENT_HIGHLIGHT (CLIENT_GROUP | CLIENT_UNGROUP) #define CLIENT_HIGHLIGHT (CLIENT_GROUP | CLIENT_UNGROUP)
#define CLIENT_MAXFLAGS (CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED) #define CLIENT_MAXFLAGS (CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED)
@ -349,7 +350,8 @@ enum {
_NET_WM_DESKTOP, _NET_WM_DESKTOP,
_NET_CLOSE_WINDOW, _NET_CLOSE_WINDOW,
_NET_WM_STATE, _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_VERT,
_NET_WM_STATE_MAXIMIZED_HORZ, _NET_WM_STATE_MAXIMIZED_HORZ,
_NET_WM_STATE_FULLSCREEN, _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_setactive(struct client_ctx *);
void client_setname(struct client_ctx *); void client_setname(struct client_ctx *);
int client_snapcalc(int, int, int, int, int); int client_snapcalc(int, int, int, int, int);
void client_sticky(struct client_ctx *);
void client_transient(struct client_ctx *); void client_transient(struct client_ctx *);
void client_unhide(struct client_ctx *); void client_unhide(struct client_ctx *);
void client_urgency(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_raise(struct client_ctx *, union arg *);
void kbfunc_client_rcycle(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_search(struct client_ctx *, union arg *);
void kbfunc_client_sticky(struct client_ctx *, union arg *);
void kbfunc_client_vmaximize(struct client_ctx *, void kbfunc_client_vmaximize(struct client_ctx *,
union arg *); union arg *);
void kbfunc_cmdexec(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; 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 void
client_fullscreen(struct client_ctx *cc) client_fullscreen(struct client_ctx *cc)
{ {
@ -468,6 +479,9 @@ 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->active = 0; cc->active = 0;
@ -481,6 +495,9 @@ 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;

3
conf.c
View File

@ -204,6 +204,7 @@ static const struct {
{ "CM-g", "grouptoggle" }, { "CM-g", "grouptoggle" },
{ "CM-f", "fullscreen" }, { "CM-f", "fullscreen" },
{ "CM-m", "maximize" }, { "CM-m", "maximize" },
{ "CM-s", "sticky" },
{ "CM-equal", "vmaximize" }, { "CM-equal", "vmaximize" },
{ "CMS-equal", "hmaximize" }, { "CMS-equal", "hmaximize" },
{ "CMS-f", "freeze" }, { "CMS-f", "freeze" },
@ -389,6 +390,7 @@ static const struct {
{ "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, {0}}, { "grouptoggle", kbfunc_client_grouptoggle, CWM_WIN, {0}},
{ "sticky", kbfunc_client_sticky, CWM_WIN, {0} },
{ "fullscreen", kbfunc_client_fullscreen, CWM_WIN, {0} }, { "fullscreen", kbfunc_client_fullscreen, CWM_WIN, {0} },
{ "maximize", kbfunc_client_maximize, CWM_WIN, {0} }, { "maximize", kbfunc_client_maximize, CWM_WIN, {0} },
{ "vmaximize", kbfunc_client_vmaximize, CWM_WIN, {0} }, { "vmaximize", kbfunc_client_vmaximize, CWM_WIN, {0} },
@ -678,6 +680,7 @@ static char *ewmhints[] = {
"_NET_WM_DESKTOP", "_NET_WM_DESKTOP",
"_NET_CLOSE_WINDOW", "_NET_CLOSE_WINDOW",
"_NET_WM_STATE", "_NET_WM_STATE",
"_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_FULLSCREEN", "_NET_WM_STATE_FULLSCREEN",

4
cwm.1
View File

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

View File

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

View File

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

View File

@ -432,6 +432,12 @@ kbfunc_client_movetogroup(struct client_ctx *cc, union arg *arg)
group_movetogroup(cc, arg->i); group_movetogroup(cc, arg->i);
} }
void
kbfunc_client_sticky(struct client_ctx *cc, union arg *arg)
{
client_sticky(cc);
}
void void
kbfunc_client_fullscreen(struct client_ctx *cc, union arg *arg) 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; int property;
void (*toggle)(struct client_ctx *); void (*toggle)(struct client_ctx *);
} handlers[] = { } handlers[] = {
{ _NET_WM_STATE_STICKY,
CLIENT_STICKY,
client_sticky },
{ _NET_WM_STATE_MAXIMIZED_VERT, { _NET_WM_STATE_MAXIMIZED_VERT,
CLIENT_VMAXIMIZED, CLIENT_VMAXIMIZED,
client_vmaximize }, 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); atoms = xu_ewmh_get_net_wm_state(cc, &n);
for (i = 0; i < n; i++) { 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]) if (atoms[i] == ewmh[_NET_WM_STATE_MAXIMIZED_HORZ])
client_hmaximize(cc); client_hmaximize(cc);
if (atoms[i] == ewmh[_NET_WM_STATE_MAXIMIZED_VERT]) 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] && if (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_FULLSCREEN] && oatoms[i] != ewmh[_NET_WM_STATE_FULLSCREEN] &&
oatoms[i] != ewmh[_NET_WM_STATE_STICKY] &&
oatoms[i] != ewmh[_NET_WM_STATE_DEMANDS_ATTENTION]) oatoms[i] != ewmh[_NET_WM_STATE_DEMANDS_ATTENTION])
atoms[j++] = oatoms[i]; atoms[j++] = oatoms[i];
} }
free(oatoms); free(oatoms);
if (cc->flags & CLIENT_STICKY)
atoms[j++] = ewmh[_NET_WM_STATE_STICKY];
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 {