Improve performance of other_frames and XTfullscreen_hook

* src/frame.c (other_frames):
* src/xterm.c (XTfullscreen_hook, x_check_fullscreen)
(x_set_window_size_1): Avoid extraneous calls to x_sync.
This commit is contained in:
Po Lu 2022-12-03 21:05:05 +08:00
parent dd7a7633be
commit 1c90138651
2 changed files with 56 additions and 13 deletions

View file

@ -1892,12 +1892,61 @@ other_frames (struct frame *f, bool invisible, bool force)
if (f != f1)
{
/* The following code is defined out because it is
responsible for a performance drop under X connections
over a network, and its purpose is unclear. XSync does
not handle events (or call any callbacks defined by
Emacs), and as such it should not note any "recent change
in visibility".
When writing new code, please try as hard as possible to
avoid calls that require a roundtrip to the X server.
When such calls are inevitable, use the XCB library to
handle multiple consecutive requests with a data reply in
a more asynchronous fashion. The following code
demonstrates why:
rc = XGetWindowProperty (dpyinfo->display, window, ...
status = XGrabKeyboard (dpyinfo->display, ...
here, `XGetWindowProperty' will wait for a reply from the
X server before returning, and thus allowing Emacs to
make the XGrabKeyboard request, which in itself also
requires waiting a reply. When XCB is available, this
code could be written:
#ifdef HAVE_XCB
xcb_get_property_cookie_t cookie1;
xcb_get_property_reply_t *reply1;
xcb_grab_keyboard_cookie_t cookie2;
xcb_grab_keyboard_reply_t *reply2;
cookie1 = xcb_get_property (dpyinfo->xcb_connection, window, ...
cookie2 = xcb_grab_keyboard (dpyinfo->xcb_connection, ...
reply1 = xcb_get_property_reply (dpyinfo->xcb_connection,
cookie1);
reply2 = xcb_grab_keyboard_reply (dpyinfo->xcb_connection,
cookie2);
#endif
In this code, the GetProperty and GrabKeyboard requests
are made simultaneously, and replies are then obtained
from the server at once, avoiding the extraneous
roundtrip to the X server after the call to
`XGetWindowProperty'.
However, please keep an alternative implementation
available for use when Emacs is built without XCB. */
#if 0
/* Verify that we can still talk to the frame's X window, and
note any recent change in visibility. */
#ifdef HAVE_X_WINDOWS
if (FRAME_WINDOW_P (f1))
x_sync (f1);
#endif
#endif
if (!FRAME_TOOLTIP_P (f1)
/* Tooltips and child frames count neither for
invisibility nor for deletions. */

View file

@ -27202,13 +27202,12 @@ do_ewmh_fullscreen (struct frame *f)
static void
XTfullscreen_hook (struct frame *f)
{
if (FRAME_VISIBLE_P (f))
{
block_input ();
x_check_fullscreen (f);
x_sync (f);
unblock_input ();
}
if (!FRAME_VISIBLE_P (f))
return;
block_input ();
x_check_fullscreen (f);
unblock_input ();
}
@ -27302,10 +27301,7 @@ x_check_fullscreen (struct frame *f)
if (FRAME_VISIBLE_P (f))
x_wait_for_event (f, ConfigureNotify);
else
{
change_frame_size (f, width, height, false, true, false);
x_sync (f);
}
change_frame_size (f, width, height, false, true, false);
}
/* `x_net_wm_state' might have reset the fullscreen frame parameter,
@ -27519,8 +27515,6 @@ x_set_window_size_1 (struct frame *f, bool change_gravity,
adjust_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, width),
FRAME_PIXEL_TO_TEXT_HEIGHT (f, height),
5, 0, Qx_set_window_size_1);
x_sync (f);
}
}