From 1c9013865183f0ea21218602917b5c16ecef465d Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sat, 3 Dec 2022 21:05:05 +0800 Subject: [PATCH] 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. --- src/frame.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/xterm.c | 20 +++++++------------- 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/src/frame.c b/src/frame.c index 05106a6c759..7d902dabd4f 100644 --- a/src/frame.c +++ b/src/frame.c @@ -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. */ diff --git a/src/xterm.c b/src/xterm.c index c775f199857..37b907ee9d2 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -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); } } -- 2.39.5