From 19fc7f666bd8e2d5956a7a3958bf6be4f5fea137 Mon Sep 17 00:00:00 2001 From: okan Date: Mon, 16 Dec 2013 19:02:17 +0000 Subject: Implement support for EWMH's _NET_WM_STATE_FULLSCREEN hint. Since we already have a form of 'maximize', we need to differentiate between 'maximize' and the new 'fullscreen' mode. The 'maximize' mode will continue to honor gap but now *retains* the border, matching the 'vert/horz maximize' behaviour. The new 'fullscreen' mode supports and follows the _NET_WM_STATE_FULLSCREEN hint, allowing the client perform additional window modifications; in this mode, cwm(1) will *ignore* gap, remove borders and freeze(move/resize) the client. Additionally, 'fullscreen' mode will remember various combinations of previous states. * default keybinding changes: CM-f 'fullscreen', CM-m 'maximize' (re-map as desired). Positive feedback from a few, testing and ok sthen@ --- calmwm.h | 9 +++++++-- client.c | 60 +++++++++++++++++++++++++++++++++++++----------------------- conf.c | 5 ++++- cwm.1 | 6 ++++-- cwmrc.5 | 10 ++++++---- kbfunc.c | 6 ++++++ xutil.c | 18 ++++++++++++++---- 7 files changed, 78 insertions(+), 36 deletions(-) diff --git a/calmwm.h b/calmwm.h index 6aa0844..6effee9 100644 --- a/calmwm.h +++ b/calmwm.h @@ -138,7 +138,7 @@ struct client_ctx { Window win; Colormap colormap; u_int bwidth; /* border width */ - struct geom geom, savegeom; + struct geom geom, savegeom, fullgeom; struct { long flags; /* defined hints */ int basew; /* desired width */ @@ -167,6 +167,7 @@ struct client_ctx { #define CLIENT_WM_DELETE_WINDOW 0x0100 #define CLIENT_WM_TAKE_FOCUS 0x0200 #define CLIENT_URGENCY 0x0400 +#define CLIENT_FULLSCREEN 0x0800 #define CLIENT_HIGHLIGHT (CLIENT_GROUP | CLIENT_UNGROUP) #define CLIENT_MAXFLAGS (CLIENT_VMAXIMIZED | CLIENT_HMAXIMIZED) @@ -355,9 +356,10 @@ enum { _NET_WM_DESKTOP, _NET_CLOSE_WINDOW, _NET_WM_STATE, -#define _NET_WM_STATES_NITEMS 3 +#define _NET_WM_STATES_NITEMS 4 _NET_WM_STATE_MAXIMIZED_VERT, _NET_WM_STATE_MAXIMIZED_HORZ, + _NET_WM_STATE_FULLSCREEN, _NET_WM_STATE_DEMANDS_ATTENTION, EWMH_NITEMS }; @@ -380,6 +382,7 @@ void client_delete(struct client_ctx *); void client_draw_border(struct client_ctx *); struct client_ctx *client_find(Window); void client_freeze(struct client_ctx *); +void client_fullscreen(struct client_ctx *); long client_get_wm_state(struct client_ctx *); void client_getsizehints(struct client_ctx *); void client_hide(struct client_ctx *); @@ -445,6 +448,8 @@ void kbfunc_client_cyclegroup(struct client_ctx *, union arg *); void kbfunc_client_delete(struct client_ctx *, union arg *); void kbfunc_client_freeze(struct client_ctx *, union arg *); +void kbfunc_client_fullscreen(struct client_ctx *, + union arg *); void kbfunc_client_group(struct client_ctx *, union arg *); void kbfunc_client_grouponly(struct client_ctx *, union arg *); diff --git a/client.c b/client.c index 0179d37..43eb001 100644 --- a/client.c +++ b/client.c @@ -228,6 +228,38 @@ client_freeze(struct client_ctx *cc) cc->flags |= CLIENT_FREEZE; } +void +client_fullscreen(struct client_ctx *cc) +{ + struct screen_ctx *sc = cc->sc; + struct geom xine; + + if ((cc->flags & CLIENT_FREEZE) && + !(cc->flags & CLIENT_FULLSCREEN)) + return; + + if ((cc->flags & CLIENT_FULLSCREEN)) { + cc->bwidth = Conf.bwidth; + cc->geom = cc->fullgeom; + cc->flags &= ~(CLIENT_FULLSCREEN | CLIENT_FREEZE); + goto resize; + } + + cc->fullgeom = cc->geom; + + xine = screen_find_xinerama(sc, + cc->geom.x + cc->geom.w / 2, + cc->geom.y + cc->geom.h / 2, CWM_NOGAP); + + cc->bwidth = 0; + cc->geom = xine; + cc->flags |= (CLIENT_FULLSCREEN | CLIENT_FREEZE); + +resize: + client_resize(cc, 0); + xu_ewmh_set_net_wm_state(cc); +} + void client_maximize(struct client_ctx *cc) { @@ -238,9 +270,8 @@ client_maximize(struct client_ctx *cc) return; if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_MAXIMIZED) { - cc->flags &= ~CLIENT_MAXIMIZED; cc->geom = cc->savegeom; - cc->bwidth = Conf.bwidth; + cc->flags &= ~CLIENT_MAXIMIZED; goto resize; } @@ -263,8 +294,10 @@ client_maximize(struct client_ctx *cc) cc->geom.x + cc->geom.w / 2, cc->geom.y + cc->geom.h / 2, CWM_GAP); - cc->geom = xine; - cc->bwidth = 0; + cc->geom.x = xine.x; + cc->geom.y = xine.y; + cc->geom.w = xine.w - (cc->bwidth * 2); + cc->geom.h = xine.h - (cc->bwidth * 2); cc->flags |= CLIENT_MAXIMIZED; resize: @@ -284,9 +317,6 @@ client_vmaximize(struct client_ctx *cc) if (cc->flags & CLIENT_VMAXIMIZED) { cc->geom.y = cc->savegeom.y; cc->geom.h = cc->savegeom.h; - cc->bwidth = Conf.bwidth; - if (cc->flags & CLIENT_HMAXIMIZED) - cc->geom.w -= cc->bwidth * 2; cc->flags &= ~CLIENT_VMAXIMIZED; goto resize; } @@ -294,12 +324,6 @@ client_vmaximize(struct client_ctx *cc) cc->savegeom.y = cc->geom.y; cc->savegeom.h = cc->geom.h; - /* if this will make us fully maximized then remove boundary */ - if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_HMAXIMIZED) { - cc->geom.w += cc->bwidth * 2; - cc->bwidth = 0; - } - xine = screen_find_xinerama(sc, cc->geom.x + cc->geom.w / 2, cc->geom.y + cc->geom.h / 2, CWM_GAP); @@ -325,9 +349,6 @@ client_hmaximize(struct client_ctx *cc) if (cc->flags & CLIENT_HMAXIMIZED) { cc->geom.x = cc->savegeom.x; cc->geom.w = cc->savegeom.w; - cc->bwidth = Conf.bwidth; - if (cc->flags & CLIENT_VMAXIMIZED) - cc->geom.h -= cc->bwidth * 2; cc->flags &= ~CLIENT_HMAXIMIZED; goto resize; } @@ -335,12 +356,6 @@ client_hmaximize(struct client_ctx *cc) cc->savegeom.x = cc->geom.x; cc->savegeom.w = cc->geom.w; - /* if this will make us fully maximized then remove boundary */ - if ((cc->flags & CLIENT_MAXFLAGS) == CLIENT_VMAXIMIZED) { - cc->geom.h += cc->bwidth * 2; - cc->bwidth = 0; - } - xine = screen_find_xinerama(sc, cc->geom.x + cc->geom.w / 2, cc->geom.y + cc->geom.h / 2, CWM_GAP); @@ -359,7 +374,6 @@ client_resize(struct client_ctx *cc, int reset) { if (reset) { cc->flags &= ~CLIENT_MAXIMIZED; - cc->bwidth = Conf.bwidth; xu_ewmh_set_net_wm_state(cc); } diff --git a/conf.c b/conf.c index 445571b..9ac0414 100644 --- a/conf.c +++ b/conf.c @@ -178,7 +178,8 @@ static struct { { "M-Right", "cyclegroup" }, { "M-Left", "rcyclegroup" }, { "CM-g", "grouptoggle" }, - { "CM-f", "maximize" }, + { "CM-f", "fullscreen" }, + { "CM-m", "maximize" }, { "CM-equal", "vmaximize" }, { "CMS-equal", "hmaximize" }, { "CMS-f", "freeze" }, @@ -376,6 +377,7 @@ static struct { { "rcycleingroup", kbfunc_client_cycle, KBFLAG_NEEDCLIENT, {.i = CWM_RCYCLE|CWM_INGROUP} }, { "grouptoggle", kbfunc_client_grouptoggle, KBFLAG_NEEDCLIENT, {0}}, + { "fullscreen", kbfunc_client_fullscreen, KBFLAG_NEEDCLIENT, {0} }, { "maximize", kbfunc_client_maximize, KBFLAG_NEEDCLIENT, {0} }, { "vmaximize", kbfunc_client_vmaximize, KBFLAG_NEEDCLIENT, {0} }, { "hmaximize", kbfunc_client_hmaximize, KBFLAG_NEEDCLIENT, {0} }, @@ -688,6 +690,7 @@ static char *ewmhints[] = { "_NET_WM_STATE", "_NET_WM_STATE_MAXIMIZED_VERT", "_NET_WM_STATE_MAXIMIZED_HORZ", + "_NET_WM_STATE_FULLSCREEN", "_NET_WM_STATE_DEMANDS_ATTENTION", }; diff --git a/cwm.1 b/cwm.1 index d647618..63c8ab2 100644 --- a/cwm.1 +++ b/cwm.1 @@ -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: May 9 2012 $ +.Dd $Mdocdate: October 31 2012 $ .Dt CWM 1 .Os .Sh NAME @@ -91,7 +91,9 @@ Reverse cycle through active groups. .It Ic CMS-f Toggle freezing geometry of current window. .It Ic CM-f -Toggle full-screen size of current window. +Toggle full-screen mode of current window. +.It Ic CM-m +Toggle maximization of current window. .It Ic CM-= Toggle vertical maximization of current window. .It Ic CMS-= diff --git a/cwmrc.5 b/cwmrc.5 index 3c3fc25..0b28ed5 100644 --- a/cwmrc.5 +++ b/cwmrc.5 @@ -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: November 27 2013 $ +.Dd $Mdocdate: December 13 2013 $ .Dt CWMRC 5 .Os .Sh NAME @@ -341,12 +341,14 @@ Raise current window. Label current window. .It freeze Freeze current window geometry. +.It fullscreen +Full-screen current window (gap + border removed). .It maximize -Maximize current window full-screen. +Maximize current window (gap + border honored). .It vmaximize -Maximize current window vertically. +Vertically maximize current window (gap + border honored). .It hmaximize -Maximize current window horizontally. +Horizontally maximize current window (gap + border honored). .It moveup Move window .Ar moveamount diff --git a/kbfunc.c b/kbfunc.c index 351366e..69c05fc 100644 --- a/kbfunc.c +++ b/kbfunc.c @@ -447,6 +447,12 @@ kbfunc_client_movetogroup(struct client_ctx *cc, union arg *arg) group_movetogroup(cc, arg->i); } +void +kbfunc_client_fullscreen(struct client_ctx *cc, union arg *arg) +{ + client_fullscreen(cc); +} + void kbfunc_client_maximize(struct client_ctx *cc, union arg *arg) { diff --git a/xutil.c b/xutil.c index 3a25304..c2c7834 100644 --- a/xutil.c +++ b/xutil.c @@ -333,6 +333,9 @@ xu_ewmh_handle_net_wm_state_msg(struct client_ctx *cc, int action, { _NET_WM_STATE_MAXIMIZED_HORZ, CLIENT_HMAXIMIZED, client_hmaximize }, + { _NET_WM_STATE_FULLSCREEN, + CLIENT_FULLSCREEN, + client_fullscreen }, { _NET_WM_STATE_DEMANDS_ATTENTION, CLIENT_URGENCY, client_urgency }, @@ -369,6 +372,8 @@ xu_ewmh_restore_net_wm_state(struct client_ctx *cc) client_hmaximize(cc); if (atoms[i] == ewmh[_NET_WM_STATE_MAXIMIZED_VERT]) client_vmaximize(cc); + if (atoms[i] == ewmh[_NET_WM_STATE_FULLSCREEN]) + client_fullscreen(cc); if (atoms[i] == ewmh[_NET_WM_STATE_DEMANDS_ATTENTION]) client_urgency(cc); } @@ -386,14 +391,19 @@ xu_ewmh_set_net_wm_state(struct client_ctx *cc) for (i = j = 0; i < n; i++) { 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_DEMANDS_ATTENTION]) atoms[j++] = oatoms[i]; } free(oatoms); - 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_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_URGENCY) atoms[j++] = ewmh[_NET_WM_STATE_DEMANDS_ATTENTION]; if (j > 0) -- cgit 1.4.1