From 3a598114bf8e786ae6d936564a372bb002fdfd20 Mon Sep 17 00:00:00 2001 From: Ali Mirjamali Date: Tue, 20 May 2025 15:40:58 +0330 Subject: [PATCH] Assure Popup Windows (override-redirect) open over parent The problem and solution is reported by `vx-sec` on Github. It was found on Xmonad WM. The fix simply raises the override-redirect window to top, flushes display events and the restack windows for "Keep-on-top" windows to work properly Also tested on the default XFCE on r4.3 resolves: https://github.com/QubesOS/qubes-issues/issues/9935 --- .gitignore | 1 + gui-daemon/xside.c | 14 ++++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index b25d2e13..696189c6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.dep tags pkgs/ +gui-daemon/qubes-guid diff --git a/gui-daemon/xside.c b/gui-daemon/xside.c index 641a953a..d2a2b0c0 100644 --- a/gui-daemon/xside.c +++ b/gui-daemon/xside.c @@ -3357,8 +3357,8 @@ static bool should_keep_on_top(Ghandles *g, Window window) { /* Move a newly mapped override_redirect window below windows that need to be - * kept on top, i.e. screen lockers. */ -static void restack_windows(Ghandles *g, struct windowdata *vm_window) + * kept on top, i.e. screen lockers. Returns new index (-1 == top of all) */ +static int restack_windows(Ghandles *g, struct windowdata *vm_window) { Window root; Window parent; @@ -3372,7 +3372,7 @@ static void restack_windows(Ghandles *g, struct windowdata *vm_window) if (!children_list) { fprintf(stderr, "XQueryTree returned an empty list\n"); - return; + return 0; } /* Traverse children_list, looking for bottom-most window that @@ -3408,6 +3408,7 @@ static void restack_windows(Ghandles *g, struct windowdata *vm_window) } XFree(children_list); + return goal_pos; } @@ -3466,7 +3467,12 @@ static void handle_map(Ghandles * g, struct windowdata *vm_window) (void) XMapWindow(g->display, vm_window->local_winid); if (vm_window->override_redirect) { - restack_windows(g, vm_window); + if (restack_windows(g, vm_window) == -1) { + // Ensure override redirect window is raised after mapping + // But only if no screensaver is active + XRaiseWindow(g->display, vm_window->local_winid); + XFlush(g->display); // Ensure raise takes effect immediately + } } }