mirror of
https://codeberg.org/dwl/dwl.git
synced 2026-06-22 07:02:45 +00:00
Compare commits
80 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7c3c5ffcc2 | |||
| 81c8ebf677 | |||
| a89872f02e | |||
| eda0613cc4 | |||
| a41d817979 | |||
| 68a17f962e | |||
| 9c592da01f | |||
| df11b7a786 | |||
| 5215712cab | |||
| 9b9b79b35e | |||
| 3d98907b98 | |||
| f8884ffc2b | |||
| a5e45924ed | |||
| 72adab621f | |||
| 0729f18dce | |||
| 797e0c74b2 | |||
| 3c760bcd4a | |||
| da77e34ee5 | |||
| 20f61a59af | |||
| 9d68554c59 | |||
| bbdf2a913b | |||
| 21930621ee | |||
| 6722a89532 | |||
| e4921fad28 | |||
| c69a2bec3f | |||
| 737688a6b1 | |||
| f8373ccf25 | |||
| 7f9a212476 | |||
| ab8334bd8a | |||
| 23ede80f74 | |||
| f7d6a34cd9 | |||
| 8653b27692 | |||
| 932c1d45f2 | |||
| dbe44e48c8 | |||
| 0b2c33248c | |||
| 56114f700f | |||
| 71c7e4e1e5 | |||
| 72d29f1654 | |||
| e523c2b82b | |||
| 6d0e3a5198 | |||
| 5347ed663d | |||
| 05f4e23c43 | |||
| be854cab35 | |||
| 6ca011430a | |||
| 7eaa01ac1f | |||
| 92e7752203 | |||
| 6682878009 | |||
| afacc9b0b5 | |||
| dd9d8d543c | |||
| 686958a4cc | |||
| 1a3d89e5b2 | |||
| 7b1fe7e5f2 | |||
| 803a9ba98d | |||
| a39a46c908 | |||
| 94c8bd6048 | |||
| c60f651951 | |||
| 79b051f242 | |||
| d42a977b5b | |||
| 4a32293548 | |||
| 9136b6247d | |||
| 19b5d47a9e | |||
| c9a0a8bf6d | |||
| 22336612ae | |||
| 38bd00351a | |||
| c56bc42eb5 | |||
| 13b929d7d7 | |||
| a4e4fd3d25 | |||
| 0259e9a8ab | |||
| b6d6127733 | |||
| 16a49e9955 | |||
| 30c24a53ad | |||
| 017bb7d752 | |||
| fac3b6f2cf | |||
| 035bb99d67 | |||
| 9c155eefdc | |||
| df34fdd483 | |||
| 04079a0946 | |||
| daf5ee475f | |||
| 156a13d9f9 | |||
| dcb7a4d910 |
@@ -14,9 +14,4 @@ wlroots version:
|
|||||||
<!--
|
<!--
|
||||||
Only report bugs that can be reproduced on the main line
|
Only report bugs that can be reproduced on the main line
|
||||||
Report patch issues to their respective authors
|
Report patch issues to their respective authors
|
||||||
If the patch author doesn't respond within a reasonable time, email me:
|
|
||||||
|
|
||||||
Leonardo Hernández Hernández <leohdz172@protonmail.com>
|
|
||||||
|
|
||||||
but note that I'm NOT making any promises
|
|
||||||
-->
|
-->
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(LIBS)
|
|||||||
all: dwl
|
all: dwl
|
||||||
dwl: dwl.o util.o
|
dwl: dwl.o util.o
|
||||||
$(CC) dwl.o util.o $(LDLIBS) $(LDFLAGS) $(DWLCFLAGS) -o $@
|
$(CC) dwl.o util.o $(LDLIBS) $(LDFLAGS) $(DWLCFLAGS) -o $@
|
||||||
dwl.o: dwl.c config.mk config.h client.h xdg-shell-protocol.h wlr-layer-shell-unstable-v1-protocol.h
|
dwl.o: dwl.c push.c config.mk config.h client.h xdg-shell-protocol.h wlr-layer-shell-unstable-v1-protocol.h
|
||||||
util.o: util.c util.h
|
util.o: util.c util.h
|
||||||
|
|
||||||
# wayland-scanner is a tool which generates C headers and rigging for Wayland
|
# wayland-scanner is a tool which generates C headers and rigging for Wayland
|
||||||
|
|||||||
@@ -16,40 +16,6 @@ client_is_x11(Client *c)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Client *
|
|
||||||
client_from_wlr_surface(struct wlr_surface *s)
|
|
||||||
{
|
|
||||||
struct wlr_xdg_surface *surface;
|
|
||||||
|
|
||||||
#ifdef XWAYLAND
|
|
||||||
struct wlr_xwayland_surface *xsurface;
|
|
||||||
if (s && wlr_surface_is_xwayland_surface(s)
|
|
||||||
&& (xsurface = wlr_xwayland_surface_from_wlr_surface(s)))
|
|
||||||
return xsurface->data;
|
|
||||||
#endif
|
|
||||||
if (s && wlr_surface_is_xdg_surface(s)
|
|
||||||
&& (surface = wlr_xdg_surface_from_wlr_surface(s))
|
|
||||||
&& surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL)
|
|
||||||
return surface->data;
|
|
||||||
|
|
||||||
if (s && wlr_surface_is_subsurface(s))
|
|
||||||
return client_from_wlr_surface(wlr_surface_get_root_surface(s));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline Client *
|
|
||||||
client_get_parent(Client *c)
|
|
||||||
{
|
|
||||||
#ifdef XWAYLAND
|
|
||||||
if (client_is_x11(c) && c->surface.xwayland->parent)
|
|
||||||
return client_from_wlr_surface(c->surface.xwayland->parent->surface);
|
|
||||||
#endif
|
|
||||||
if (c->surface.xdg->toplevel->parent)
|
|
||||||
return client_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
client_get_size_hints(Client *c, struct wlr_box *max, struct wlr_box *min)
|
client_get_size_hints(Client *c, struct wlr_box *max, struct wlr_box *min)
|
||||||
{
|
{
|
||||||
@@ -85,6 +51,69 @@ client_surface(Client *c)
|
|||||||
return c->surface.xdg->surface;
|
return c->surface.xdg->surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
toplevel_from_wlr_surface(struct wlr_surface *s, Client **pc, LayerSurface **pl)
|
||||||
|
{
|
||||||
|
struct wlr_xdg_surface *xdg_surface;
|
||||||
|
struct wlr_surface *root_surface;
|
||||||
|
struct wlr_layer_surface_v1 *layer_surface;
|
||||||
|
Client *c = NULL;
|
||||||
|
LayerSurface *l = NULL;
|
||||||
|
int type = -1;
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
struct wlr_xwayland_surface *xsurface;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!s)
|
||||||
|
return type;
|
||||||
|
root_surface = wlr_surface_get_root_surface(s);
|
||||||
|
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (wlr_surface_is_xwayland_surface(root_surface)
|
||||||
|
&& (xsurface = wlr_xwayland_surface_from_wlr_surface(root_surface))) {
|
||||||
|
c = xsurface->data;
|
||||||
|
type = c->type;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (wlr_surface_is_layer_surface(root_surface)
|
||||||
|
&& (layer_surface = wlr_layer_surface_v1_from_wlr_surface(root_surface))) {
|
||||||
|
l = layer_surface->data;
|
||||||
|
type = LayerShell;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wlr_surface_is_xdg_surface(root_surface)
|
||||||
|
&& (xdg_surface = wlr_xdg_surface_from_wlr_surface(root_surface))) {
|
||||||
|
while (1) {
|
||||||
|
switch (xdg_surface->role) {
|
||||||
|
case WLR_XDG_SURFACE_ROLE_POPUP:
|
||||||
|
if (!xdg_surface->popup->parent)
|
||||||
|
return -1;
|
||||||
|
else if (!wlr_surface_is_xdg_surface(xdg_surface->popup->parent))
|
||||||
|
return toplevel_from_wlr_surface(xdg_surface->popup->parent, pc, pl);
|
||||||
|
|
||||||
|
xdg_surface = wlr_xdg_surface_from_wlr_surface(xdg_surface->popup->parent);
|
||||||
|
break;
|
||||||
|
case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
|
||||||
|
c = xdg_surface->data;
|
||||||
|
type = c->type;
|
||||||
|
goto end;
|
||||||
|
case WLR_XDG_SURFACE_ROLE_NONE:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (pl)
|
||||||
|
*pl = l;
|
||||||
|
if (pc)
|
||||||
|
*pc = c;
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
/* The others */
|
/* The others */
|
||||||
static inline void
|
static inline void
|
||||||
client_activate_surface(struct wlr_surface *s, int activated)
|
client_activate_surface(struct wlr_surface *s, int activated)
|
||||||
@@ -112,7 +141,7 @@ client_set_bounds(Client *c, int32_t width, int32_t height)
|
|||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
if (c->surface.xdg->client->shell->version >=
|
if (c->surface.xdg->client->shell->version >=
|
||||||
XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION)
|
XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION && width >= 0 && height >= 0)
|
||||||
return wlr_xdg_toplevel_set_bounds(c->surface.xdg->toplevel, width, height);
|
return wlr_xdg_toplevel_set_bounds(c->surface.xdg->toplevel, width, height);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -153,6 +182,20 @@ client_get_geometry(Client *c, struct wlr_box *geom)
|
|||||||
wlr_xdg_surface_get_geometry(c->surface.xdg, geom);
|
wlr_xdg_surface_get_geometry(c->surface.xdg, geom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline Client *
|
||||||
|
client_get_parent(Client *c)
|
||||||
|
{
|
||||||
|
Client *p = NULL;
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c) && c->surface.xwayland->parent)
|
||||||
|
toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL);
|
||||||
|
#endif
|
||||||
|
if (c->surface.xdg->toplevel->parent)
|
||||||
|
toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface, &p, NULL);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
static inline const char *
|
static inline const char *
|
||||||
client_get_title(Client *c)
|
client_get_title(Client *c)
|
||||||
{
|
{
|
||||||
@@ -197,6 +240,47 @@ client_is_mapped(Client *c)
|
|||||||
return c->surface.xdg->mapped;
|
return c->surface.xdg->mapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
client_is_rendered_on_mon(Client *c, Monitor *m)
|
||||||
|
{
|
||||||
|
/* This is needed for when you don't want to check formal assignment,
|
||||||
|
* but rather actual displaying of the pixels.
|
||||||
|
* Usually VISIBLEON suffices and is also faster. */
|
||||||
|
struct wlr_surface_output *s;
|
||||||
|
if (!c->scene->node.enabled)
|
||||||
|
return 0;
|
||||||
|
wl_list_for_each(s, &client_surface(c)->current_outputs, link)
|
||||||
|
if (s->output == m->wlr_output)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
client_is_stopped(Client *c)
|
||||||
|
{
|
||||||
|
int pid;
|
||||||
|
siginfo_t in = {0};
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
if (client_is_x11(c))
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
wl_client_get_credentials(c->surface.xdg->client->client, &pid, NULL, NULL);
|
||||||
|
if (waitid(P_PID, pid, &in, WNOHANG|WCONTINUED|WSTOPPED|WNOWAIT) < 0) {
|
||||||
|
/* This process is not our child process, while is very unluckely that
|
||||||
|
* it is stopped, in order to do not skip frames assume that it is. */
|
||||||
|
if (errno == ECHILD)
|
||||||
|
return 1;
|
||||||
|
} else if (in.si_pid) {
|
||||||
|
if (in.si_code == CLD_STOPPED || in.si_code == CLD_TRAPPED)
|
||||||
|
return 1;
|
||||||
|
if (in.si_code == CLD_CONTINUED)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
client_is_unmanaged(Client *c)
|
client_is_unmanaged(Client *c)
|
||||||
{
|
{
|
||||||
@@ -261,6 +345,9 @@ client_set_size(Client *c, uint32_t width, uint32_t height)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (width == c->surface.xdg->toplevel->current.width
|
||||||
|
&& height ==c->surface.xdg->toplevel->current.height)
|
||||||
|
return 0;
|
||||||
return wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, width, height);
|
return wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,43 +392,3 @@ client_wants_fullscreen(Client *c)
|
|||||||
#endif
|
#endif
|
||||||
return c->surface.xdg->toplevel->requested.fullscreen;
|
return c->surface.xdg->toplevel->requested.fullscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *
|
|
||||||
toplevel_from_popup(struct wlr_xdg_popup *popup)
|
|
||||||
{
|
|
||||||
struct wlr_xdg_surface *surface = popup->base;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
switch (surface->role) {
|
|
||||||
case WLR_XDG_SURFACE_ROLE_POPUP:
|
|
||||||
if (!surface->popup->parent)
|
|
||||||
return NULL;
|
|
||||||
else if (wlr_surface_is_layer_surface(surface->popup->parent))
|
|
||||||
return wlr_layer_surface_v1_from_wlr_surface(surface->popup->parent)->data;
|
|
||||||
else if (!wlr_surface_is_xdg_surface(surface->popup->parent))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
surface = wlr_xdg_surface_from_wlr_surface(surface->popup->parent);
|
|
||||||
break;
|
|
||||||
case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
|
|
||||||
return surface->data;
|
|
||||||
case WLR_XDG_SURFACE_ROLE_NONE:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void *
|
|
||||||
toplevel_from_wlr_layer_surface(struct wlr_surface *s)
|
|
||||||
{
|
|
||||||
Client *c;
|
|
||||||
struct wlr_layer_surface_v1 *wlr_layer_surface;
|
|
||||||
|
|
||||||
if ((c = client_from_wlr_surface(s)))
|
|
||||||
return c;
|
|
||||||
else if (s && wlr_surface_is_layer_surface(s)
|
|
||||||
&& (wlr_layer_surface = wlr_layer_surface_v1_from_wlr_surface(s)))
|
|
||||||
return wlr_layer_surface->data;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|||||||
+13
-9
@@ -2,14 +2,13 @@
|
|||||||
static const int sloppyfocus = 1; /* focus follows mouse */
|
static const int sloppyfocus = 1; /* focus follows mouse */
|
||||||
static const int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible */
|
static const int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible */
|
||||||
static const unsigned int borderpx = 1; /* border pixel of windows */
|
static const unsigned int borderpx = 1; /* border pixel of windows */
|
||||||
static const float rootcolor[] = {0.3, 0.3, 0.3, 1.0};
|
|
||||||
static const float bordercolor[] = {0.5, 0.5, 0.5, 1.0};
|
static const float bordercolor[] = {0.5, 0.5, 0.5, 1.0};
|
||||||
static const float focuscolor[] = {1.0, 0.0, 0.0, 1.0};
|
static const float focuscolor[] = {1.0, 0.0, 0.0, 1.0};
|
||||||
/* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */
|
/* To conform the xdg-protocol, set the alpha to zero to restore the old behavior */
|
||||||
static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0};
|
static const float fullscreen_bg[] = {0.1, 0.1, 0.1, 1.0};
|
||||||
|
|
||||||
/* tagging */
|
/* tagging - tagcount must be no greater than 31 */
|
||||||
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
|
static const int tagcount = 9;
|
||||||
|
|
||||||
static const Rule rules[] = {
|
static const Rule rules[] = {
|
||||||
/* app_id title tags mask isfloating monitor */
|
/* app_id title tags mask isfloating monitor */
|
||||||
@@ -29,12 +28,12 @@ static const Layout layouts[] = {
|
|||||||
|
|
||||||
/* monitors */
|
/* monitors */
|
||||||
static const MonitorRule monrules[] = {
|
static const MonitorRule monrules[] = {
|
||||||
/* name mfact nmaster scale layout rotate/reflect */
|
/* name mfact nmaster scale layout rotate/reflect x y */
|
||||||
/* example of a HiDPI laptop monitor:
|
/* example of a HiDPI laptop monitor:
|
||||||
{ "eDP-1", 0.5, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL },
|
{ "eDP-1", 0.5, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },
|
||||||
*/
|
*/
|
||||||
/* defaults */
|
/* defaults */
|
||||||
{ NULL, 0.55, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL },
|
{ NULL, 0.55, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* keyboard */
|
/* keyboard */
|
||||||
@@ -66,9 +65,9 @@ LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN
|
|||||||
static const enum libinput_config_scroll_method scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
|
static const enum libinput_config_scroll_method scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
|
||||||
|
|
||||||
/* You can choose between:
|
/* You can choose between:
|
||||||
LIBINPUT_CONFIG_CLICK_METHOD_NONE
|
LIBINPUT_CONFIG_CLICK_METHOD_NONE
|
||||||
LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS
|
LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS
|
||||||
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER
|
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER
|
||||||
*/
|
*/
|
||||||
static const enum libinput_config_click_method click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
|
static const enum libinput_config_click_method click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
|
||||||
|
|
||||||
@@ -85,6 +84,11 @@ LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE
|
|||||||
*/
|
*/
|
||||||
static const enum libinput_config_accel_profile accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
|
static const enum libinput_config_accel_profile accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
|
||||||
static const double accel_speed = 0.0;
|
static const double accel_speed = 0.0;
|
||||||
|
/* You can choose between:
|
||||||
|
LIBINPUT_CONFIG_TAP_MAP_LRM -- 1/2/3 finger tap maps to left/right/middle
|
||||||
|
LIBINPUT_CONFIG_TAP_MAP_LMR -- 1/2/3 finger tap maps to left/middle/right
|
||||||
|
*/
|
||||||
|
static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TAP_MAP_LRM;
|
||||||
|
|
||||||
/* If you want to use the windows key for MODKEY, use WLR_MODIFIER_LOGO */
|
/* If you want to use the windows key for MODKEY, use WLR_MODIFIER_LOGO */
|
||||||
#define MODKEY WLR_MODIFIER_ALT
|
#define MODKEY WLR_MODIFIER_ALT
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
_VERSION = 0.4-rc1
|
_VERSION = 0.4
|
||||||
VERSION = `git describe --long --tags --dirty 2>/dev/null || echo $(_VERSION)`
|
VERSION = `git describe --tags --dirty 2>/dev/null || echo $(_VERSION)`
|
||||||
|
|
||||||
PKG_CONFIG = pkg-config
|
PKG_CONFIG = pkg-config
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ Spawn
|
|||||||
.Nm bemenu-run .
|
.Nm bemenu-run .
|
||||||
.It Mod-Shift-Return
|
.It Mod-Shift-Return
|
||||||
Spawn
|
Spawn
|
||||||
.Nm alacritty .
|
.Nm foot .
|
||||||
.It Mod-[jk]
|
.It Mod-[jk]
|
||||||
Move focus down/up the stack.
|
Move focus down/up the stack.
|
||||||
.It Mod-[id]
|
.It Mod-[id]
|
||||||
@@ -135,7 +135,7 @@ Start
|
|||||||
with s6 in the background:
|
with s6 in the background:
|
||||||
.Dl dwl -s 's6-svscan <&-'
|
.Dl dwl -s 's6-svscan <&-'
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr alacritty 1 ,
|
.Xr foot 1 ,
|
||||||
.Xr bemenu 1 ,
|
.Xr bemenu 1 ,
|
||||||
.Xr dwm 1 ,
|
.Xr dwm 1 ,
|
||||||
.Xr xkeyboard-config 7
|
.Xr xkeyboard-config 7
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
static Client *
|
||||||
|
nexttiled(Client *sel) {
|
||||||
|
Client *c;
|
||||||
|
wl_list_for_each(c, &sel->link, link) {
|
||||||
|
if (&c->link == &clients)
|
||||||
|
break; /* don't wrap */
|
||||||
|
if (!c->isfloating && VISIBLEON(c, selmon))
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Client *
|
||||||
|
prevtiled(Client *sel) {
|
||||||
|
Client *c;
|
||||||
|
wl_list_for_each_reverse(c, &sel->link, link) {
|
||||||
|
if (&c->link == &clients)
|
||||||
|
break; /* don't wrap */
|
||||||
|
if (!c->isfloating && VISIBLEON(c, selmon))
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pushup(const Arg *arg) {
|
||||||
|
Client *sel = focustop(selmon);
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
if(!sel || sel->isfloating)
|
||||||
|
return;
|
||||||
|
if((c = prevtiled(sel))) {
|
||||||
|
/* attach before c */
|
||||||
|
wl_list_remove(&sel->link);
|
||||||
|
wl_list_insert(c->link.prev, &sel->link);
|
||||||
|
} else {
|
||||||
|
/* move to the end */
|
||||||
|
wl_list_remove(&sel->link);
|
||||||
|
wl_list_insert(clients.prev, &sel->link);
|
||||||
|
}
|
||||||
|
focusclient(sel, 1);
|
||||||
|
arrange(selmon);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pushdown(const Arg *arg) {
|
||||||
|
Client *sel = focustop(selmon);
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
if(!sel || sel->isfloating)
|
||||||
|
return;
|
||||||
|
if((c = nexttiled(sel))) {
|
||||||
|
/* attach after c */
|
||||||
|
wl_list_remove(&sel->link);
|
||||||
|
wl_list_insert(&c->link, &sel->link);
|
||||||
|
} else {
|
||||||
|
/* move to the front */
|
||||||
|
wl_list_remove(&sel->link);
|
||||||
|
wl_list_insert(&clients, &sel->link);
|
||||||
|
}
|
||||||
|
focusclient(sel, 1);
|
||||||
|
arrange(selmon);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user