]> git.eshelyaron.com Git - emacs.git/commitdiff
Better respect window manager stacking order
authorPo Lu <luangruo@yahoo.com>
Sun, 5 Jun 2022 05:02:58 +0000 (13:02 +0800)
committerPo Lu <luangruo@yahoo.com>
Sun, 5 Jun 2022 05:05:56 +0000 (13:05 +0800)
* src/xfns.c (x_frame_list_z_order, Fx_frame_list_z_order): Use
_NET_CLIENT_LIST_STACKING if supported.
* src/xterm.c (x_wm_supports_1): New function.  Accept dpyinfo
instead of frame.
(x_wm_supports): Use that function instead.

* src/xterm.h: Update prototypes.

src/xfns.c
src/xterm.c
src/xterm.h

index e3763a558934c0971f45d72b3129c3e7a2c81904..cfc6d4c212e000185de923b6de7cc42e750af1a0 100644 (file)
@@ -6600,17 +6600,61 @@ menu bar or tool bar of FRAME.  */)
  * WINDOW to FRAMES and return FRAMES.
  */
 static Lisp_Object
-x_frame_list_z_order (Display* dpy, Window window)
+x_frame_list_z_order (struct x_display_info *dpyinfo, Window window)
 {
+  Display *dpy;
   Window root, parent, *children;
   unsigned int nchildren;
-  int i;
-  Lisp_Object frames = Qnil;
+  unsigned long i;
+  Lisp_Object frames, val;
+  Atom type;
+  Window *toplevels;
+  int format, rc;
+  unsigned long nitems, bytes_after;
+  unsigned char *data;
+  struct frame *f;
+
+  dpy = dpyinfo->display;
+  data = NULL;
+  frames = Qnil;
+
+  if (window == dpyinfo->root_window
+      && x_wm_supports_1 (dpyinfo,
+                         dpyinfo->Xatom_net_client_list_stacking))
+    {
+      rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
+                              dpyinfo->Xatom_net_client_list_stacking,
+                              0, LONG_MAX, False, XA_WINDOW, &type,
+                              &format, &nitems, &bytes_after, &data);
+
+      if (rc != Success)
+       return Qnil;
+
+      if (format != 32 || type != XA_WINDOW)
+       {
+         XFree (data);
+         return Qnil;
+       }
+
+      toplevels = (Window *) data;
+
+      for (i = 0; i < nitems; ++i)
+       {
+         f = x_top_window_to_frame (dpyinfo, toplevels[i]);
+
+         if (f)
+           {
+             XSETFRAME (val, f);
+             frames = Fcons (val, frames);
+           }
+       }
+
+      XFree (data);
+      return frames;
+    }
 
-  block_input ();
   if (XQueryTree (dpy, window, &root, &parent, &children, &nchildren))
     {
-      unblock_input ();
       for (i = 0; i < nchildren; i++)
        {
          Lisp_Object frame, tail;
@@ -6628,10 +6672,9 @@ x_frame_list_z_order (Display* dpy, Window window)
             }
        }
 
-      if (children) XFree ((char *)children);
+      if (children)
+       XFree (children);
     }
-  else
-    unblock_input ();
 
   return frames;
 }
@@ -6652,7 +6695,6 @@ Frames are listed from topmost (first) to bottommost (last).  */)
   (Lisp_Object terminal)
 {
   struct x_display_info *dpyinfo = check_x_display_info (terminal);
-  Display *dpy = dpyinfo->display;
   Window window;
 
   if (FRAMEP (terminal) && FRAME_LIVE_P (XFRAME (terminal)))
@@ -6660,7 +6702,7 @@ Frames are listed from topmost (first) to bottommost (last).  */)
   else
     window = dpyinfo->root_window;
 
-  return x_frame_list_z_order (dpy, window);
+  return x_frame_list_z_order (dpyinfo, window);
 }
 
 /**
index 2bf37e94d6b0d2667aab9effd4179b9535ada1bf..3b60dba69bdfb0c682a2a269be7606d3c52d6004 100644 (file)
@@ -22591,17 +22591,16 @@ x_set_offset (struct frame *f, int xoff, int yoff, int change_gravity)
    https://freedesktop.org/wiki/Specifications/wm-spec/.  */
 
 bool
-x_wm_supports (struct frame *f, Atom want_atom)
+x_wm_supports_1 (struct x_display_info *dpyinfo, Atom want_atom)
 {
   Atom actual_type;
   unsigned long actual_size, bytes_remaining;
   int i, rc, actual_format;
   bool ret;
   Window wmcheck_window;
-  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
   Window target_window = dpyinfo->root_window;
   int max_len = 65536;
-  Display *dpy = FRAME_X_DISPLAY (f);
+  Display *dpy = dpyinfo->display;
   unsigned char *tmp_data = NULL;
   Atom target_type = XA_WINDOW;
 
@@ -22675,6 +22674,13 @@ x_wm_supports (struct frame *f, Atom want_atom)
   return ret;
 }
 
+bool
+x_wm_supports (struct frame *f, Atom want_atom)
+{
+  return x_wm_supports_1 (FRAME_DISPLAY_INFO (f),
+                         want_atom);
+}
+
 static void
 set_wm_state (Lisp_Object frame, bool add, Atom atom, Atom value)
 {
index d7e184ed9f1ce384054ecc2eef03bccbd15eea83..878cb5fd87b846159f382c07ded2dfc33da48704 100644 (file)
@@ -1497,6 +1497,7 @@ extern void x_set_shaded (struct frame *, Lisp_Object, Lisp_Object);
 extern void x_set_skip_taskbar (struct frame *, Lisp_Object, Lisp_Object);
 extern void x_set_z_group (struct frame *, Lisp_Object, Lisp_Object);
 extern bool x_wm_supports (struct frame *, Atom);
+extern bool x_wm_supports_1 (struct x_display_info *, Atom);
 extern void x_wait_for_event (struct frame *, int);
 extern void x_clear_under_internal_border (struct frame *f);