Better respect window manager stacking order

* 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.
This commit is contained in:
Po Lu 2022-06-05 13:02:58 +08:00
parent d46e94f23f
commit 7d7a6f6719
3 changed files with 62 additions and 13 deletions

View 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);
}
/**

View 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)
{

View 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);