diff --git a/client.h b/client.h index 56e30897b..64287fd9f 100644 --- a/client.h +++ b/client.h @@ -152,6 +152,35 @@ client_set_tiled(Client *c, uint32_t edges) WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT); } +static inline pid_t +client_get_pid(Client *c) +{ + pid_t pid; + if (client_is_x11(c)) + pid = c->surface.xwayland->pid; + else + wl_client_get_credentials(c->surface.xdg->client->client, &pid, NULL, NULL); + + return pid; +} + +static inline Client * +client_get_parent(Client *c) +{ + Client *p; + pid_t c_pid, p_pid; + if (!(c_pid = client_get_pid(c))) + return NULL; + + wl_list_for_each(p, &clients, link) { + p_pid = client_get_pid(p); + if (c != p && p_pid && isdescprocess(p_pid, c_pid)) + return p; + } + + return NULL; +} + static inline struct wlr_surface * client_surface(Client *c) { diff --git a/dwl.c b/dwl.c index 2732a4cca..9df808725 100644 --- a/dwl.c +++ b/dwl.c @@ -268,6 +268,8 @@ static void focusmon(const Arg *arg); static void focusstack(const Arg *arg); static void fullscreennotify(struct wl_listener *listener, void *data); static Client *focustop(Monitor *m); +static pid_t getparentprocess(pid_t pid); +static int isdescprocess(pid_t p, pid_t c); static int hidecursor(void *data); static int movecursor(void *data); static void incnmaster(const Arg *arg); @@ -523,6 +525,7 @@ applyrules(Client *c) const char *appid, *title; unsigned int i, newtags = 0; const Rule *r; + Client *p; Monitor *mon = selmon, *m; c->isfloating = client_is_float_type(c); @@ -535,11 +538,16 @@ applyrules(Client *c) if ((!r->title || strstr(title, r->title)) && (!r->id || strstr(appid, r->id))) { c->isfloating = r->isfloating; - newtags |= r->tags; - i = 0; - wl_list_for_each(m, &mons, link) - if (r->monitor == i++) - mon = m; + if ((p = client_get_parent(c))) { + newtags |= p->tags; + mon = p->mon; + } else { + newtags |= r->tags; + i = 0; + wl_list_for_each(m, &mons, link) + if (r->monitor == i++) + mon = m; + } } } c->geom.x = (mon->w.width - c->geom.width) / 2; @@ -1369,6 +1377,33 @@ focustop(Monitor *m) return NULL; } +pid_t +getparentprocess(pid_t p) +{ + unsigned int v = 0; + + FILE *f; + char buf[256]; + snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)p); + + 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); + + return (int)c; +} + int movecursor(void *data) {