diff --git a/config.def.h b/config.def.h index 13c5322..0af77b2 100644 --- a/config.def.h +++ b/config.def.h @@ -137,6 +137,7 @@ static const Key keys[] = { { MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} }, { MODKEY, XKB_KEY_space, setlayout, {0} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} }, + { MODKEY|WLR_MODIFIER_ALT, XKB_KEY_space, togglealwaysontop, {0} }, { MODKEY, XKB_KEY_e, togglefullscreen, {0} }, { MODKEY, XKB_KEY_0, view, {.ui = ~0} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_0, tag, {.ui = ~0} }, diff --git a/dwl.c b/dwl.c index c51e0d5..a6c9a05 100644 --- a/dwl.c +++ b/dwl.c @@ -88,7 +88,7 @@ /* enums */ enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */ enum { XDGShell, LayerShell, X11 }; /* client types */ -enum { LyrBg, LyrBottom, LyrTile, LyrFloat, LyrTop, LyrFS, LyrUnmanaged, LyrOverlay, +enum { LyrBg, LyrBottom, LyrTile, LyrFloat, LyrAlwaysTop, LyrTop, LyrFS, LyrUnmanaged, LyrOverlay, LyrIMPopup, LyrBlock, NUM_LAYERS }; /* scene layers */ enum { AxisUp, AxisRight, AxisDown, AxisLeft }; @@ -158,7 +158,7 @@ typedef struct { #endif unsigned int bw; uint32_t tags; - int isfloating, isurgent, isfullscreen; + int isfloating, isurgent, isfullscreen, isalwaysontop; } Client; typedef struct { @@ -355,6 +355,7 @@ static void startdrag(struct wl_listener *listener, void *data); static void tag(const Arg *arg); static void tagmon(const Arg *arg); static void tile(Monitor *m); +static void togglealwaysontop(const Arg *arg); static void togglefloating(const Arg *arg); static void togglefullscreen(const Arg *arg); static void toggletag(const Arg *arg); @@ -565,7 +566,7 @@ arrange(Monitor *m) /* We move all clients (except fullscreen and unmanaged) to LyrTile while * in floating layout to avoid "real" floating clients be always on top */ wl_list_for_each(c, &clients, link) { - if (c->mon != m || c->scene->node.parent == layers[LyrFS]) + if (c->mon != m || c->scene->node.parent == layers[LyrFS] || c->isalwaysontop) continue; wlr_scene_node_reparent(&c->scene->node, @@ -2487,7 +2488,8 @@ setfloating(Client *c, int floating) return; wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen || (p && p->isfullscreen) ? LyrFS - : c->isfloating ? LyrFloat : LyrTile]); + : c->isfloating ? (c->isalwaysontop ? LyrAlwaysTop : LyrFloat) : LyrTile]); + arrange(c->mon); printstatus(); } @@ -2501,7 +2503,8 @@ setfullscreen(Client *c, int fullscreen) c->bw = fullscreen ? 0 : borderpx; client_set_fullscreen(c, fullscreen); wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen - ? LyrFS : c->isfloating ? LyrFloat : LyrTile]); + ? LyrFS : c->isfloating ? (c->isalwaysontop ? LyrAlwaysTop : LyrFloat) : LyrTile]); + if (fullscreen) { c->prev = c->geom; @@ -2515,6 +2518,27 @@ setfullscreen(Client *c, int fullscreen) printstatus(); } +void +togglealwaysontop(const Arg *arg) +{ + Client *sel = focustop(selmon); + if (!sel) + return; + + if (sel->isfullscreen) + return; + + if (sel->isalwaysontop) { + wlr_scene_node_reparent(&sel->scene->node, layers[sel->isalwaysontop]); + sel->isalwaysontop = 0; + } else { + sel->isalwaysontop = sel->isfullscreen ? LyrFS : LyrTile; + wlr_scene_node_reparent(&sel->scene->node, layers[LyrAlwaysTop]); + } + arrange(selmon); +} + + void setlayout(const Arg *arg) {