The current implementation of `sync_wins`, which gets called after
control is returned to ratpoison following a call to `tmpwm`, gets
executed once per screen.

This is not only unnecesary, but also causes ratpoison to break after
returning from `tmpwm`. This is due to two things: first, we can scan
for the windows in only one pass, because the call to `XQueryTree`
returns all windows below the root window, which is shared across the
screens. Second, the current implementation only checks whether a
window is a special ratpoison window (i.e. the key window, bar window,
etc.) for the current screen. This results in some windows being
mapped although they shouldn't be, which is what causes the break
preventing ratpoison from receiving commands correctly,

This patch fixes these issues by only running `sync_wins` once instead
of on all screens, and by using the existing `is_rp_window` utility
function to prevent a special ratpoison window from being mapped,
regardless of the screen it belongs to.

Signed-off-by: Antoine Busque <>
 src/actions.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/src/actions.c b/src/actions.c
index a044f7a..21237ee 100644
--- a/src/actions.c
+++ b/src/actions.c
@@ -4949,12 +4949,15 @@ cmd_warp (int interactive UNUSED, struct cmdarg **args)
 static void
-sync_wins (rp_screen *s)
+sync_wins (void)
+  rp_screen *s;
   rp_window *win, *wintmp;
   XWindowAttributes attr;
   unsigned int i, nwins;
   Window dw1, dw2, *wins;
+  list_first (s, &rp_screens, node);
   XQueryTree(dpy, s->root, &dw1, &dw2, &wins, &nwins);
   /* Remove any windows in our cached lists that aren't in the query
@@ -5009,11 +5012,7 @@ sync_wins (rp_screen *s)
   for (i=0; i<nwins; i++)
       XGetWindowAttributes(dpy, wins[i], &attr);
-      if (wins[i] == s->bar_window
-          || wins[i] == s->key_window
-          || wins[i] == s->input_window
-          || wins[i] == s->frame_window
-          || wins[i] == s->help_window
+      if (is_rp_window (wins[i])
           || attr.override_redirect == True) continue;
       /* Find the window in our mapped window list. */
@@ -5195,10 +5194,7 @@ cmd_tmpwm (int interactive UNUSED, struct cmdarg **args)
   /* Sort through all the windows in each group and pick out the ones
      that are unmapped or destroyed. */
-  list_for_each_entry (cur_screen, &rp_screens, node)
-    {
-      sync_wins (cur_screen);
-    }
+  sync_wins ();
   /* At this point, new windows have the top level keys grabbed but
      existing windows don't. So grab them on all windows just to be

Ratpoison-devel mailing list

Reply via email to