mirror of
https://codeberg.org/dwl/dwl-patches.git
synced 2025-09-07 11:44:51 +00:00
swallow: rewrite patch, update README.md
This commit is contained in:
parent
4d0bfa66b4
commit
2e5748edfe
@ -1,29 +1,52 @@
|
||||
### Description
|
||||
Terminals swallow windows that they are the parent of.
|
||||
|
||||
foot is the terminal by default, you can change it in client rules in config.h.
|
||||
|
||||
2023-08-16 and up are made to also work with x windows: https://codeberg.org/dwl/dwl/issues/331
|
||||
|
||||
for freebsd users: apply swallow-freebsd.patch **on top of** swallow.patch
|
||||
|
||||
### Download
|
||||
- [git branch](https://codeberg.org/notchoc/dwl/src/branch/swallow)
|
||||
- [2024-07-13](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/swallow/swallow.patch)
|
||||
### Description
|
||||
|
||||
This patch adds "window swallowing" to dwl.
|
||||
|
||||
If a user runs a graphical program from the terminal (e.g., `mpv`), the terminal
|
||||
will be hidden and only a window of the newly spawned graphical program will
|
||||
be visible. The terminal stays hidden until the graphical program is closed.
|
||||
This patch helps users spawning a lot of graphical programs from their command
|
||||
line by avoiding cluttering the screen with many unusable terminals.
|
||||
|
||||
`foot` is the terminal by default, you can change it in client rules in config.h.
|
||||
|
||||
In `2025-03-03 v0.7` version, the patch had been rewritten from scratch to make
|
||||
it more robust and add a few more features:
|
||||
|
||||
- "dynamically swallow" windows by pressing `Alt+a` (a focused window will
|
||||
swallow/unswallow the previously focused one)
|
||||
- toggle automatic swallowing by `Alt+Shift+a`
|
||||
- if a window has swallowed another, it get thicker borders
|
||||
|
||||
### Download
|
||||
|
||||
#### swallow.patch
|
||||
|
||||
- [git branch](https://codeberg.org/nikitaivanov/dwl/src/branch/swallow)
|
||||
- [2025-03-03 v0.7](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/swallow/swallow.patch) (added "dynamic swallowing support")
|
||||
- [2024-07-13](https://codeberg.org/dwl/dwl-patches/raw/commit/f1ed83eaeba46108f4ee8164094cb431d64a3e68/patches/swallow/swallow.patch)
|
||||
- [2024-07-13](https://codeberg.org/dwl/dwl-patches/raw/commit/f64d701bab2f9f52d3637edd091684f920407d87/patches/swallow/swallow.patch)
|
||||
- [2024-05-02](https://codeberg.org/dwl/dwl-patches/raw/commit/9c5d5d85f3ac780e7a14d5d0535e3349ce8b8f53/patches/swallow/swallow.patch)
|
||||
- [2024-04-03](https://codeberg.org/dwl/dwl-patches/raw/commit/3c9a8e3232a8531871924484cef1ef0938730e15/swallow/swallow.patch)
|
||||
- [2024-01-01](https://codeberg.org/dwl/dwl-patches/raw/commit/8a352a1b27a64821ba9fbfda52fe82463ac84c66/swallow/swallow.patch)
|
||||
- [2023-10-26](https://github.com/djpohly/dwl/compare/main...youbitchoc:swallow.patch)
|
||||
- [2023-08-16](https://github.com/djpohly/dwl/compare/main...mewkl:swallowx.patch)
|
||||
- [2023-07-15](https://github.com/djpohly/dwl/compare/main...NikitaIvanovV:swallow.patch)
|
||||
- [v0.4](https://github.com/djpohly/dwl/compare/main...dm1tz:04-swallow.patch)
|
||||
- [2021-12-03](https://github.com/djpohly/dwl/compare/main...dm1tz:swallow.patch)
|
||||
|
||||
### Authors
|
||||
- [Dmitry Zakharchenko](https://github.com/dm1tz)
|
||||
- [Palanix](https://codeberg.org/Palanix)
|
||||
- [Nikita Ivanov](https://github.com/NikitaIvanovV)
|
||||
- [Connor Worrell](https://github.com/ConnorWorrell)
|
||||
- [Mewkl](https://github.com/mewkl)
|
||||
- [Choc](https://codeberg.org/notchoc)
|
||||
- [2024-05-02](https://codeberg.org/dwl/dwl-patches/raw/commit/9c5d5d85f3ac780e7a14d5d0535e3349ce8b8f53/patches/swallow/swallow.patch)
|
||||
- [2024-04-03](https://codeberg.org/dwl/dwl-patches/raw/commit/3c9a8e3232a8531871924484cef1ef0938730e15/swallow/swallow.patch)
|
||||
- [2024-01-01](https://codeberg.org/dwl/dwl-patches/raw/commit/8a352a1b27a64821ba9fbfda52fe82463ac84c66/swallow/swallow.patch)
|
||||
- [2023-10-26](https://github.com/djpohly/dwl/compare/main...youbitchoc:swallow.patch)
|
||||
- [2023-08-16](https://github.com/djpohly/dwl/compare/main...mewkl:swallowx.patch) (added XWayland support)
|
||||
- [2023-07-15](https://github.com/djpohly/dwl/compare/main...NikitaIvanovV:swallow.patch)
|
||||
- [v0.4](https://github.com/djpohly/dwl/compare/main...dm1tz:04-swallow.patch)
|
||||
- [2021-12-03](https://github.com/djpohly/dwl/compare/main...dm1tz:swallow.patch)
|
||||
|
||||
#### swallow-freebsd.patch
|
||||
|
||||
Apply this patch on top of the swallow.patch if you use FreeBSD.
|
||||
|
||||
- [2025-03-03 v0.7](https://codeberg.org/dwl/dwl-patches/raw/branch/main/patches/swallow/swallow-freebsd.patch)
|
||||
- [2024-07-13](https://codeberg.org/dwl/dwl-patches/raw/commit/f1ed83eaeba46108f4ee8164094cb431d64a3e68/patches/swallow/swallow-freebsd.patch)
|
||||
|
||||
### Authors
|
||||
|
||||
- [Nikita Ivanov](https://codeberg.org/nikitaivanov) ([GitHub](https://github.com/NikitaIvanovV))
|
||||
- [Dmitry Zakharchenko](https://github.com/dm1tz)
|
||||
- [Palanix](https://codeberg.org/Palanix)
|
||||
- [Connor Worrell](https://github.com/ConnorWorrell)
|
||||
- [Mewkl](https://github.com/mewkl)
|
||||
- [Choc](https://codeberg.org/notchoc)
|
||||
|
@ -1,17 +1,17 @@
|
||||
From 49dc947ba4c33324b969ef7179768c806910fffb Mon Sep 17 00:00:00 2001
|
||||
From: choc <notchoc@proton.me>
|
||||
Date: Sat, 22 Jun 2024 10:52:33 +0800
|
||||
Subject: [PATCH] swallow: add freebsd support
|
||||
From 002e11e197cd254f06b65681ffd5bcf617d830b9 Mon Sep 17 00:00:00 2001
|
||||
From: Nikita Ivanov <nikita.vyach.ivanov@gmail.com>
|
||||
Date: Mon, 3 Mar 2025 19:49:07 +0100
|
||||
Subject: [PATCH] swallow: add FreeBSD support
|
||||
|
||||
---
|
||||
dwl.c | 17 +++++++++++++++++
|
||||
1 file changed, 17 insertions(+)
|
||||
|
||||
diff --git a/dwl.c b/dwl.c
|
||||
index 3a3167b..ee9e965 100644
|
||||
index bbbbe6f..dc55319 100644
|
||||
--- a/dwl.c
|
||||
+++ b/dwl.c
|
||||
@@ -65,6 +65,14 @@
|
||||
@@ -67,6 +67,14 @@
|
||||
#include <xcb/xcb_icccm.h>
|
||||
#endif
|
||||
|
||||
@ -26,17 +26,17 @@ index 3a3167b..ee9e965 100644
|
||||
#include "util.h"
|
||||
|
||||
/* macros */
|
||||
@@ -1486,6 +1494,7 @@ handlesig(int signo)
|
||||
@@ -2032,6 +2040,7 @@ outputmgrtest(struct wl_listener *listener, void *data)
|
||||
pid_t
|
||||
getparentprocess(pid_t p)
|
||||
parentpid(pid_t pid)
|
||||
{
|
||||
+#ifdef __linux__
|
||||
unsigned int v = 0;
|
||||
|
||||
FILE *f;
|
||||
@@ -1499,6 +1508,14 @@ getparentprocess(pid_t p)
|
||||
char buf[256];
|
||||
@@ -2041,6 +2050,14 @@ parentpid(pid_t pid)
|
||||
fscanf(f, "%*u %*s %*c %u", &v);
|
||||
fclose(f);
|
||||
|
||||
return (pid_t)v;
|
||||
+#elif defined(__FreeBSD__)
|
||||
+ struct kinfo_proc kip;
|
||||
@ -48,8 +48,7 @@ index 3a3167b..ee9e965 100644
|
||||
+#endif
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
--
|
||||
2.43.0
|
||||
|
||||
2.48.1
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
From 4b80c425c9f414bc079a0e61f5a3ef42eea85476 Mon Sep 17 00:00:00 2001
|
||||
From: choc <notchoc@proton.me>
|
||||
Date: Fri, 15 Sep 2023 10:36:21 +0800
|
||||
Subject: [PATCH] implement swallow
|
||||
From 7255d7e2e1b87c0583a202ea20c83fa75466c0fc Mon Sep 17 00:00:00 2001
|
||||
From: Nikita Ivanov <nikita.vyach.ivanov@gmail.com>
|
||||
Date: Wed, 5 Feb 2025 02:34:39 +0100
|
||||
Subject: [PATCH] Swallow: hide the terminal when it spawns a client
|
||||
|
||||
---
|
||||
client.h | 12 ++++++
|
||||
config.def.h | 7 ++--
|
||||
dwl.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++---
|
||||
3 files changed, 123 insertions(+), 8 deletions(-)
|
||||
client.h | 12 ++++
|
||||
config.def.h | 10 +++-
|
||||
dwl.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++++--
|
||||
3 files changed, 167 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/client.h b/client.h
|
||||
index 42f225f..bc9cad2 100644
|
||||
@ -33,29 +33,61 @@ index 42f225f..bc9cad2 100644
|
||||
client_get_clip(Client *c, struct wlr_box *clip)
|
||||
{
|
||||
diff --git a/config.def.h b/config.def.h
|
||||
index 22d2171..7e5fef1 100644
|
||||
index 22d2171..fb5f8fb 100644
|
||||
--- a/config.def.h
|
||||
+++ b/config.def.h
|
||||
@@ -22,10 +22,11 @@ static int log_level = WLR_ERROR;
|
||||
@@ -13,6 +13,7 @@ static const float focuscolor[] = COLOR(0x005577ff);
|
||||
static const float urgentcolor[] = COLOR(0xff0000ff);
|
||||
/* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */
|
||||
static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */
|
||||
+static int enableautoswallow = 1; /* enables autoswallowing newly spawned clients */
|
||||
|
||||
/* tagging - TAGCOUNT must be no greater than 31 */
|
||||
#define TAGCOUNT (9)
|
||||
@@ -22,10 +23,11 @@ static int log_level = WLR_ERROR;
|
||||
|
||||
/* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */
|
||||
static const Rule rules[] = {
|
||||
- /* app_id title tags mask isfloating monitor */
|
||||
+ /* app_id title tags mask isfloating isterm noswallow monitor */
|
||||
+ /* app_id title tags mask isfloating isterm noswallow monitor */
|
||||
/* examples: */
|
||||
- { "Gimp_EXAMPLE", NULL, 0, 1, -1 }, /* Start on currently visible tags floating, not tiled */
|
||||
- { "firefox_EXAMPLE", NULL, 1 << 8, 0, -1 }, /* Start on ONLY tag "9" */
|
||||
+ { "Gimp_EXAMPLE", NULL, 0, 1, 0, 0, -1 }, /* Start on currently visible tags floating, not tiled */
|
||||
+ { "firefox_EXAMPLE", NULL, 1 << 8, 0, 0, 0, -1 }, /* Start on ONLY tag "9" */
|
||||
+ { "foot", NULL, 0, 0, 1, 1, -1 }, /* make foot swallow clients that are not foot */
|
||||
+ { "foot", NULL, 0, 0, 1, 1, -1 },
|
||||
+ { "Gimp_EXAMPLE", NULL, 0, 1, 0, 0, -1 }, /* Start on currently visible tags floating, not tiled */
|
||||
+ { "firefox_EXAMPLE", NULL, 1 << 8, 0, 0, 0, -1 }, /* Start on ONLY tag "9" */
|
||||
};
|
||||
|
||||
/* layout(s) */
|
||||
@@ -142,6 +144,8 @@ static const Key keys[] = {
|
||||
{ MODKEY, XKB_KEY_space, setlayout, {0} },
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
|
||||
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
|
||||
+ { MODKEY, XKB_KEY_a, toggleswallow, {0} },
|
||||
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_A, toggleautoswallow,{0} },
|
||||
{ MODKEY, XKB_KEY_0, view, {.ui = ~0} },
|
||||
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} },
|
||||
{ MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} },
|
||||
diff --git a/dwl.c b/dwl.c
|
||||
index dc0437e..c6a5e9d 100644
|
||||
index def2562..bbbbe6f 100644
|
||||
--- a/dwl.c
|
||||
+++ b/dwl.c
|
||||
@@ -103,7 +103,8 @@ typedef struct {
|
||||
@@ -73,12 +73,13 @@
|
||||
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
||||
#define CLEANMASK(mask) (mask & ~WLR_MODIFIER_CAPS)
|
||||
-#define VISIBLEON(C, M) ((M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags]))
|
||||
+#define VISIBLEON(C, M) ((M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags]) && !(C)->swallowedby)
|
||||
#define LENGTH(X) (sizeof X / sizeof X[0])
|
||||
#define END(A) ((A) + LENGTH(A))
|
||||
#define TAGMASK ((1u << TAGCOUNT) - 1)
|
||||
#define LISTEN(E, L, H) wl_signal_add((E), ((L)->notify = (H), (L)))
|
||||
#define LISTEN_STATIC(E, H) do { static struct wl_listener _l = {.notify = (H)}; wl_signal_add((E), &_l); } while (0)
|
||||
+#define BORDERPX(C) (borderpx + ((C)->swallowing ? (C)->swallowing->bw : 0))
|
||||
|
||||
/* enums */
|
||||
enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */
|
||||
@@ -104,7 +105,8 @@ typedef struct {
|
||||
} Button;
|
||||
|
||||
typedef struct Monitor Monitor;
|
||||
@ -65,21 +97,21 @@ index dc0437e..c6a5e9d 100644
|
||||
/* Must keep these three elements in this order */
|
||||
unsigned int type; /* XDGShell or X11* */
|
||||
struct wlr_box geom; /* layout-relative, includes border */
|
||||
@@ -138,9 +139,11 @@ typedef struct {
|
||||
#endif
|
||||
@@ -140,8 +142,12 @@ typedef struct {
|
||||
unsigned int bw;
|
||||
uint32_t tags;
|
||||
- int isfloating, isurgent, isfullscreen;
|
||||
+ int isfloating, isurgent, isfullscreen, isterm, noswallow;
|
||||
int isfloating, isurgent, isfullscreen;
|
||||
+ int isterm, noswallow;
|
||||
uint32_t resize; /* configure serial of a pending resize */
|
||||
-} Client;
|
||||
+ pid_t pid;
|
||||
+ Client *swallowing, *swallowedby;
|
||||
+ Client *swallowing; /* client being hidden */
|
||||
+ Client *swallowedby;
|
||||
+};
|
||||
|
||||
typedef struct {
|
||||
uint32_t mod;
|
||||
@@ -229,6 +232,8 @@ typedef struct {
|
||||
@@ -230,6 +236,8 @@ typedef struct {
|
||||
const char *title;
|
||||
uint32_t tags;
|
||||
int isfloating;
|
||||
@ -88,18 +120,31 @@ index dc0437e..c6a5e9d 100644
|
||||
int monitor;
|
||||
} Rule;
|
||||
|
||||
@@ -351,6 +356,10 @@ static Monitor *xytomon(double x, double y);
|
||||
static void xytonode(double x, double y, struct wlr_surface **psurface,
|
||||
Client **pc, LayerSurface **pl, double *nx, double *ny);
|
||||
static void zoom(const Arg *arg);
|
||||
+static pid_t getparentprocess(pid_t p);
|
||||
+static int isdescprocess(pid_t p, pid_t c);
|
||||
+static Client *termforwin(Client *w);
|
||||
+static void swallow(Client *c, Client *w);
|
||||
|
||||
/* variables */
|
||||
static const char broken[] = "broken";
|
||||
@@ -461,10 +470,14 @@ applyrules(Client *c)
|
||||
@@ -311,6 +319,7 @@ static void moveresize(const Arg *arg);
|
||||
static void outputmgrapply(struct wl_listener *listener, void *data);
|
||||
static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config, int test);
|
||||
static void outputmgrtest(struct wl_listener *listener, void *data);
|
||||
+static pid_t parentpid(pid_t pid);
|
||||
static void pointerfocus(Client *c, struct wlr_surface *surface,
|
||||
double sx, double sy, uint32_t time);
|
||||
static void printstatus(void);
|
||||
@@ -335,11 +344,15 @@ static void setsel(struct wl_listener *listener, void *data);
|
||||
static void setup(void);
|
||||
static void spawn(const Arg *arg);
|
||||
static void startdrag(struct wl_listener *listener, void *data);
|
||||
+static void swallow(Client *c, Client *toswallow);
|
||||
static void tag(const Arg *arg);
|
||||
static void tagmon(const Arg *arg);
|
||||
+static Client *termforwin(Client *c);
|
||||
static void tile(Monitor *m);
|
||||
static void togglefloating(const Arg *arg);
|
||||
static void togglefullscreen(const Arg *arg);
|
||||
+static void toggleswallow(const Arg *arg);
|
||||
+static void toggleautoswallow(const Arg *arg);
|
||||
static void toggletag(const Arg *arg);
|
||||
static void toggleview(const Arg *arg);
|
||||
static void unlocksession(struct wl_listener *listener, void *data);
|
||||
@@ -466,11 +479,15 @@ applyrules(Client *c)
|
||||
if (!(title = client_get_title(c)))
|
||||
title = broken;
|
||||
|
||||
@ -109,132 +154,197 @@ index dc0437e..c6a5e9d 100644
|
||||
if ((!r->title || strstr(title, r->title))
|
||||
&& (!r->id || strstr(appid, r->id))) {
|
||||
c->isfloating = r->isfloating;
|
||||
+ c->isterm = r->isterm;
|
||||
+ c->noswallow = r->noswallow;
|
||||
newtags |= r->tags;
|
||||
+ c->isterm = r->isterm;
|
||||
+ c->noswallow = r->noswallow;
|
||||
i = 0;
|
||||
wl_list_for_each(m, &mons, link) {
|
||||
@@ -473,6 +486,21 @@ applyrules(Client *c)
|
||||
if (r->monitor == i++)
|
||||
@@ -478,6 +495,12 @@ applyrules(Client *c)
|
||||
}
|
||||
}
|
||||
}
|
||||
+ if (!c->noswallow && !client_is_float_type(c)
|
||||
+ && !c->surface.xdg->initial_commit) {
|
||||
+ if (enableautoswallow && !c->noswallow && !c->isfloating &&
|
||||
+ !c->surface.xdg->initial_commit) {
|
||||
+ Client *p = termforwin(c);
|
||||
+ if (p) {
|
||||
+ c->swallowedby = p;
|
||||
+ p->swallowing = c;
|
||||
+ wl_list_remove(&c->link);
|
||||
+ wl_list_remove(&c->flink);
|
||||
+ if (p)
|
||||
+ swallow(c, p);
|
||||
+ wl_list_remove(&p->link);
|
||||
+ wl_list_remove(&p->flink);
|
||||
+ mon = p->mon;
|
||||
+ newtags = p->tags;
|
||||
+ }
|
||||
+ }
|
||||
setmon(c, mon, newtags);
|
||||
}
|
||||
|
||||
@@ -1467,6 +1495,63 @@ handlesig(int signo)
|
||||
}
|
||||
@@ -2006,6 +2029,20 @@ outputmgrtest(struct wl_listener *listener, void *data)
|
||||
outputmgrapplyortest(config, 1);
|
||||
}
|
||||
|
||||
+pid_t
|
||||
+getparentprocess(pid_t p)
|
||||
+parentpid(pid_t pid)
|
||||
+{
|
||||
+ unsigned int v = 0;
|
||||
+
|
||||
+ FILE *f;
|
||||
+ char buf[256];
|
||||
+ snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p);
|
||||
+
|
||||
+ snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)pid);
|
||||
+ if (!(f = fopen(buf, "r")))
|
||||
+ return 0;
|
||||
+
|
||||
+ fscanf(f, "%*u %*s %*c %u", &v);
|
||||
+ fclose(f);
|
||||
+
|
||||
+ return (pid_t)v;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+isdescprocess(pid_t p, pid_t c)
|
||||
+{
|
||||
+ while (p != c && c != 0)
|
||||
+ c = getparentprocess(c);
|
||||
void
|
||||
pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy,
|
||||
uint32_t time)
|
||||
@@ -2326,7 +2363,7 @@ setfullscreen(Client *c, int fullscreen)
|
||||
c->isfullscreen = fullscreen;
|
||||
if (!c->mon || !client_surface(c)->mapped)
|
||||
return;
|
||||
- c->bw = fullscreen ? 0 : borderpx;
|
||||
+ c->bw = fullscreen ? 0 : BORDERPX(c);
|
||||
client_set_fullscreen(c, fullscreen);
|
||||
wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen
|
||||
? LyrFS : c->isfloating ? LyrFloat : LyrTile]);
|
||||
@@ -2404,6 +2441,9 @@ setmon(Client *c, Monitor *m, uint32_t newtags)
|
||||
setfloating(c, c->isfloating);
|
||||
}
|
||||
focusclient(focustop(selmon), 1);
|
||||
+
|
||||
+ return (int)c;
|
||||
+ if (c->swallowing)
|
||||
+ setmon(c->swallowing, m, newtags);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2669,6 +2709,44 @@ startdrag(struct wl_listener *listener, void *data)
|
||||
LISTEN_STATIC(&drag->icon->events.destroy, destroydragicon);
|
||||
}
|
||||
|
||||
+void
|
||||
+swallow(Client *c, Client *toswallow)
|
||||
+{
|
||||
+ /* Do not allow a client to swallow itself */
|
||||
+ if (c == toswallow)
|
||||
+ return;
|
||||
+
|
||||
+ /* Swallow */
|
||||
+ if (toswallow && !c->swallowing) {
|
||||
+ c->swallowing = toswallow;
|
||||
+ toswallow->swallowedby = c;
|
||||
+ toswallow->mon = c->mon;
|
||||
+ toswallow->mon = c->mon;
|
||||
+ wl_list_remove(&c->link);
|
||||
+ wl_list_insert(&c->swallowing->link, &c->link);
|
||||
+ wl_list_remove(&c->flink);
|
||||
+ wl_list_insert(&c->swallowing->flink, &c->flink);
|
||||
+ c->bw = BORDERPX(c);
|
||||
+ c->tags = toswallow->tags;
|
||||
+ c->isfloating = toswallow->isfloating;
|
||||
+ c->geom = toswallow->geom;
|
||||
+ setfullscreen(toswallow, 0);
|
||||
+ }
|
||||
+
|
||||
+ /* Unswallow */
|
||||
+ else if (c->swallowing) {
|
||||
+ wl_list_remove(&c->swallowing->link);
|
||||
+ wl_list_insert(&c->link, &c->swallowing->link);
|
||||
+ wl_list_remove(&c->swallowing->flink);
|
||||
+ wl_list_insert(&c->flink, &c->swallowing->flink);
|
||||
+ c->swallowing->tags = c->tags;
|
||||
+ c->swallowing->swallowedby = NULL;
|
||||
+ c->swallowing = NULL;
|
||||
+ c->bw = BORDERPX(c);
|
||||
+ setfullscreen(c, 0);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void
|
||||
tag(const Arg *arg)
|
||||
{
|
||||
@@ -2690,6 +2768,40 @@ tagmon(const Arg *arg)
|
||||
setmon(sel, dirtomon(arg->i), 0);
|
||||
}
|
||||
|
||||
+Client *
|
||||
+termforwin(Client *w)
|
||||
+termforwin(Client *c)
|
||||
+{
|
||||
+ Client *c;
|
||||
+ Client *p;
|
||||
+ pid_t pid;
|
||||
+ pid_t pids[32];
|
||||
+ size_t i, pids_len;
|
||||
+
|
||||
+ if (!w->pid || w->isterm || w->noswallow)
|
||||
+ if (!c->pid || c->isterm)
|
||||
+ return NULL;
|
||||
+
|
||||
+ wl_list_for_each(c, &fstack, flink)
|
||||
+ if (c->isterm && !c->swallowing && c->pid && isdescprocess(c->pid, w->pid))
|
||||
+ return c;
|
||||
+ /* Get all parent pids */
|
||||
+ pids_len = 0;
|
||||
+ pid = c->pid;
|
||||
+ while (pids_len < LENGTH(pids)) {
|
||||
+ pid = parentpid(pid);
|
||||
+ if (!pid)
|
||||
+ break;
|
||||
+ pids[pids_len++] = pid;
|
||||
+ }
|
||||
+
|
||||
+ /* Find closest parent */
|
||||
+ for (i = 0; i < pids_len; i++) {
|
||||
+ wl_list_for_each(p, &clients, link) {
|
||||
+ if (!p->pid || !p->isterm || p->swallowedby)
|
||||
+ continue;
|
||||
+ if (pids[i] == p->pid)
|
||||
+ return p;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
void
|
||||
tile(Monitor *m)
|
||||
{
|
||||
@@ -2741,6 +2853,32 @@ togglefullscreen(const Arg *arg)
|
||||
setfullscreen(sel, !sel->isfullscreen);
|
||||
}
|
||||
|
||||
+void
|
||||
+swallow(Client *c, Client *w)
|
||||
+toggleswallow(const Arg *arg)
|
||||
+{
|
||||
+ c->bw = w->bw;
|
||||
+ c->isfloating = w->isfloating;
|
||||
+ c->isurgent = w->isurgent;
|
||||
+ c->isfullscreen = w->isfullscreen;
|
||||
+ c->tags = w->tags;
|
||||
+ c->geom = w->geom;
|
||||
+ wl_list_insert(&w->link, &c->link);
|
||||
+ wl_list_insert(&w->flink, &c->flink);
|
||||
+ wlr_scene_node_set_enabled(&w->scene->node, 0);
|
||||
+ wlr_scene_node_set_enabled(&c->scene->node, 1);
|
||||
+ Client *c, *sel = focustop(selmon);
|
||||
+ if (!sel)
|
||||
+ return;
|
||||
+
|
||||
+ if (sel->swallowing) {
|
||||
+ swallow(sel, NULL);
|
||||
+ } else {
|
||||
+ wl_list_for_each(c, &sel->flink, flink) {
|
||||
+ if (&c->flink == &fstack)
|
||||
+ continue; /* wrap past the sentinel node */
|
||||
+ if (VISIBLEON(c, selmon))
|
||||
+ break; /* found it */
|
||||
+ }
|
||||
+ swallow(sel, c);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+toggleautoswallow(const Arg *arg)
|
||||
+{
|
||||
+ enableautoswallow = !enableautoswallow;
|
||||
+}
|
||||
+
|
||||
void
|
||||
incnmaster(const Arg *arg)
|
||||
toggletag(const Arg *arg)
|
||||
{
|
||||
@@ -2746,15 +2831,32 @@ unmapnotify(struct wl_listener *listener, void *data)
|
||||
@@ -2801,6 +2939,12 @@ unmapnotify(struct wl_listener *listener, void *data)
|
||||
grabc = NULL;
|
||||
}
|
||||
|
||||
+ if (c->swallowedby)
|
||||
+ swallow(c->swallowedby, c);
|
||||
+ if (c->swallowing) {
|
||||
+ swallow(c, NULL);
|
||||
+ } else if (c->swallowedby) {
|
||||
+ swallow(c->swallowedby, NULL);
|
||||
+ }
|
||||
+
|
||||
if (client_is_unmanaged(c)) {
|
||||
if (c == exclusive_focus) {
|
||||
exclusive_focus = NULL;
|
||||
focusclient(focustop(selmon), 1);
|
||||
}
|
||||
} else {
|
||||
- wl_list_remove(&c->link);
|
||||
+ if (!c->swallowing)
|
||||
+ wl_list_remove(&c->link);
|
||||
setmon(c, NULL, 0);
|
||||
- wl_list_remove(&c->flink);
|
||||
+ if (!c->swallowing)
|
||||
+ wl_list_remove(&c->flink);
|
||||
+ }
|
||||
+
|
||||
+ if (c->swallowedby) {
|
||||
+ c->swallowedby->prev = c->geom;
|
||||
+ setfullscreen(c->swallowedby, c->isfullscreen);
|
||||
+ c->swallowedby->swallowing = NULL;
|
||||
+ c->swallowedby = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (c->swallowing) {
|
||||
+ c->swallowing->swallowedby = NULL;
|
||||
+ c->swallowing = NULL;
|
||||
}
|
||||
|
||||
wlr_scene_node_destroy(&c->scene->node);
|
||||
--
|
||||
2.43.0
|
||||
2.48.1
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user