From 5325d815af43a36ea8571851e272c3d39bc19252 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 12 Dec 2022 19:21:10 +0800 Subject: [PATCH] Add variable to make resizing frames sometimes faster * etc/PROBLEMS: Add documentation about new variable. * src/xterm.c (x_set_offset, x_set_window_size_1): Respect new variable. (syms_of_xterm): Add a new variable to prevent Emacs from syncing upon resize or movement. --- etc/PROBLEMS | 10 ++++-- src/xterm.c | 86 +++++++++++++++++++++++++++++++++------------------- 2 files changed, 62 insertions(+), 34 deletions(-) diff --git a/etc/PROBLEMS b/etc/PROBLEMS index 68f7cdb0560..b6d2d63660c 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -1712,8 +1712,8 @@ which can be carried out at the same time: 7) If selecting text with the mouse is slow, the main culprit is likely `select-active-regions', coupled with a program monitoring - the clipboard on the X server you are connected to. Try turning - that off. + the clipboard or primary selection on the X server you are + connected to. Try turning that off. However, over networks with moderate to high latency, with no clipboard monitor running, the bottleneck is likely to be @@ -1723,6 +1723,12 @@ which can be carried out at the same time: cause Emacs features that relies on accurate mouse position reporting to stop working reliably. +8) If creating or resizing frames is slow, turn off + `frame-resize-pixelwise' (this will not take effect until you + create a new frame); then, enable `x-lax-frame-geometry'. This + means frame placement will be less accurate, but makes frame + creation, movement, and resize visibly faster. + *** Emacs gives the error, Couldn't find per display information. This can result if the X server runs out of memory because Emacs uses diff --git a/src/xterm.c b/src/xterm.c index 38775c3f52e..3c8dbce30e7 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -26693,38 +26693,43 @@ x_set_offset (struct frame *f, int xoff, int yoff, int change_gravity) modified_left, modified_top); #endif - /* 'x_sync_with_move' is too costly for dragging child frames. */ - if (!FRAME_PARENT_FRAME (f) - /* If no window manager exists, just calling XSync will be - sufficient to ensure that the window geometry has been - updated. */ - && NILP (Vx_no_window_manager)) - { - x_sync_with_move (f, f->left_pos, f->top_pos, - FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN); - - /* change_gravity is non-zero when this function is called from Lisp to - programmatically move a frame. In that case, we call - x_check_expected_move to discover if we have a "Type A" or "Type B" - window manager, and, for a "Type A" window manager, adjust the position - of the frame. - - We call x_check_expected_move if a programmatic move occurred, and - either the window manager type (A/B) is unknown or it is Type A but we - need to compute the top/left offset adjustment for this frame. */ - - if (change_gravity != 0 - && (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN - || (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A - && (FRAME_X_OUTPUT (f)->move_offset_left == 0 - && FRAME_X_OUTPUT (f)->move_offset_top == 0)))) - x_check_expected_move (f, modified_left, modified_top); - } - /* Instead, just wait for the last ConfigureWindow request to - complete. No window manager is involved when moving child - frames. */ - else - XSync (FRAME_X_DISPLAY (f), False); + /* The following code is too slow over a latent network + connection. */ + if (NILP (Vx_lax_frame_positioning)) + { + /* 'x_sync_with_move' is too costly for dragging child frames. */ + if (!FRAME_PARENT_FRAME (f) + /* If no window manager exists, just calling XSync will be + sufficient to ensure that the window geometry has been + updated. */ + && NILP (Vx_no_window_manager)) + { + x_sync_with_move (f, f->left_pos, f->top_pos, + FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN); + + /* change_gravity is non-zero when this function is called from Lisp to + programmatically move a frame. In that case, we call + x_check_expected_move to discover if we have a "Type A" or "Type B" + window manager, and, for a "Type A" window manager, adjust the position + of the frame. + + We call x_check_expected_move if a programmatic move occurred, and + either the window manager type (A/B) is unknown or it is Type A but we + need to compute the top/left offset adjustment for this frame. */ + + if (change_gravity != 0 + && (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN + || (FRAME_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A + && (FRAME_X_OUTPUT (f)->move_offset_left == 0 + && FRAME_X_OUTPUT (f)->move_offset_top == 0)))) + x_check_expected_move (f, modified_left, modified_top); + } + /* Instead, just wait for the last ConfigureWindow request to + complete. No window manager is involved when moving child + frames. */ + else + XSync (FRAME_X_DISPLAY (f), False); + } unblock_input (); } @@ -27533,6 +27538,12 @@ x_set_window_size_1 (struct frame *f, bool change_gravity, we have to make sure to do it here. */ SET_FRAME_GARBAGED (f); + /* The following code is too slow over a latent network + connection, so skip it when the user says so. */ + + if (!NILP (Vx_lax_frame_positioning)) + return; + /* Now, strictly speaking, we can't be sure that this is accurate, but the window manager will get around to dealing with the size change request eventually, and we'll hear how it went when the @@ -31859,4 +31870,15 @@ check whether or not a resulting Access error is generated by the X server. If the X server reports the error, Emacs will disable certain features that do not work for untrusted clients. */); Vx_detect_server_trust = Qnil; + + DEFVAR_LISP ("x-lax-frame-geometry", Vx_lax_frame_positioning, + doc: /* If non-nil nil, Emacs won't compensate for WM geometry behavior. + +Setting this to non-nil is useful when the compensation proves to be +too slow, which is usually true when the X server is located over a +network connection with high latency. Doing so will make frame +creation and placement faster at the cost of reducing the accuracy of +frame placement via frame properties, `set-frame-position', and +`set-frame-size'. */); + Vx_lax_frame_positioning = Qnil; } -- 2.39.2