summaryrefslogtreecommitdiff
path: root/src/sxwm.c
diff options
context:
space:
mode:
authorL0Wigh <mathiotthomas@gmail.com>2025-09-11 14:57:13 +0200
committerL0Wigh <mathiotthomas@gmail.com>2025-09-11 14:57:13 +0200
commitfaba2d069e4b7bcbfaf70866dc7302ec10db0da5 (patch)
treebc106609b0434344fb9d4f1948c13647b3cfaa5e /src/sxwm.c
parent5becdb32e03c937edabf9205d6b0bbf30a2ae950 (diff)
fix window swallowing to target it's really parent window
Diffstat (limited to 'src/sxwm.c')
-rw-r--r--src/sxwm.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/src/sxwm.c b/src/sxwm.c
index ce936df..6cb5007 100644
--- a/src/sxwm.c
+++ b/src/sxwm.c
@@ -43,6 +43,7 @@
Client *add_client(Window w, int ws);
/* void centre_window(void); */
void change_workspace(int ws);
+int check_parent(pid_t p, pid_t c);
int clean_mask(int mask);
/* void close_focused(void); */
/* void dec_gaps(void); */
@@ -53,6 +54,7 @@ Window find_toplevel(Window w);
/* void focus_next_mon(void); */
/* void focus_prev_mon(void); */
int get_monitor_for(Client *c);
+pid_t get_parent_process(pid_t c);
pid_t get_pid(Window w);
int get_workspace_for_window(Window w);
void grab_button(Mask button, Mask mod, Window w, Bool owner_events, Mask masks);
@@ -308,6 +310,23 @@ void centre_window(void)
XMoveWindow(dpy, focused->win, x, y);
}
+pid_t get_parent_process(pid_t c)
+{
+ unsigned int v = 0;
+ FILE *f;
+ char buf[256];
+
+ snprintf(buf, sizeof(buf) - 1, "/proc/%u/stat", (unsigned)c);
+ if (!(f = fopen(buf, "r"))) {
+ return 0;
+ }
+
+ int no_error = fscanf(f, "%*u %*s %*c %u", &v);
+ (void)no_error;
+ fclose(f);
+ return (pid_t)v;
+}
+
void change_workspace(int ws)
{
if (ws >= NUM_WORKSPACES || ws == current_ws) {
@@ -423,6 +442,14 @@ void change_workspace(int ws)
in_ws_switch = False;
}
+int check_parent(pid_t p, pid_t c)
+{
+ while (p != c && c != 0) {
+ c = get_parent_process(c);
+ }
+ return (int)c;
+}
+
int clean_mask(int mask)
{
return mask & ~(LockMask | numlock_mask | mode_switch_mask);
@@ -1192,7 +1219,6 @@ void hdl_map_req(XEvent *xev)
}
/* if window can be swallowed look for a potential swallower */
- // Should be swallowed by it's parent and not any windows that can swallow
if (can_be_swallowed) {
for (Client *p = workspaces[current_ws]; p; p = p->next) {
if (p == c || p->swallowed || !p->mapped) {
@@ -1217,8 +1243,8 @@ void hdl_map_req(XEvent *xev)
}
/* check process relationship */
- if (can_swallow) {
- /* we know class matches -> swallow now */
+ if (can_swallow && check_parent(p->pid, c->pid)) {
+ /* we know class matches and the swallower is the parent -> swallow now */
swallow_window(p, c);
XFree(pch.res_class);
XFree(pch.res_name);