aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2022-11-18 09:08:59 +0800
committerPo Lu2022-11-18 09:09:10 +0800
commit32e29afe64897c2ba821e1c2edc2b7d2eb74e70f (patch)
treee2e1ef06d23f5654c9e435019d4e6e560f8bf2b4
parent682b068ba712075cea34d8bc790620ba82169d6c (diff)
downloademacs-32e29afe64897c2ba821e1c2edc2b7d2eb74e70f.tar.gz
emacs-32e29afe64897c2ba821e1c2edc2b7d2eb74e70f.zip
Add knob to make `mouse-position' faster on X
* etc/PROBLEMS (Improving performance with slow X connections): Add new advice. * src/xterm.c (XTmouse_position): Add alternative implementations for slow connections. (syms_of_xterm): Add new variable to enable them. * src/xterm.h (struct x_display_info): Update commentary.
-rw-r--r--etc/PROBLEMS56
-rw-r--r--src/xterm.c123
-rw-r--r--src/xterm.h21
3 files changed, 170 insertions, 30 deletions
diff --git a/etc/PROBLEMS b/etc/PROBLEMS
index aaecc41f6e8..2169ed0f80b 100644
--- a/etc/PROBLEMS
+++ b/etc/PROBLEMS
@@ -1640,16 +1640,21 @@ X expects to find it.
1640 1640
1641*** Improving performance with slow X connections. 1641*** Improving performance with slow X connections.
1642 1642
1643There are several ways to improve this performance, any subset of which can 1643There are several ways to improve this performance, any subset of
1644be carried out at the same time: 1644which can be carried out at the same time:
1645 1645
16461) If you don't need X Input Methods (XIM) for entering text in some 16461) Use the "--with-x-toolkit=no" build of Emacs. By not relying on
1647 any toolkit (exhibiting potentially slow behavior), it has been
1648 made very fast over networks exhibiting high latency, but suitable
1649 bandwidth.
1650
16512) If you don't need X Input Methods (XIM) for entering text in some
1647 language you use, you can improve performance on WAN links by using 1652 language you use, you can improve performance on WAN links by using
1648 the X resource useXIM to turn off use of XIM. This does not affect 1653 the X resource useXIM to turn off use of XIM. This does not affect
1649 the use of Emacs's own input methods, which are part of the Leim 1654 the use of Emacs's own input methods, which are part of the Leim
1650 package. 1655 package.
1651 1656
16522) If the connection is very slow, you might also want to consider 16573) If the connection is very slow, you might also want to consider
1653 switching off scroll bars, menu bar, and tool bar. Adding the 1658 switching off scroll bars, menu bar, and tool bar. Adding the
1654 following forms to your .emacs file will accomplish that, but only 1659 following forms to your .emacs file will accomplish that, but only
1655 after the initial frame is displayed: 1660 after the initial frame is displayed:
@@ -1665,26 +1670,45 @@ be carried out at the same time:
1665 Emacs.menuBar: off 1670 Emacs.menuBar: off
1666 Emacs.toolBar: off 1671 Emacs.toolBar: off
1667 1672
16683) Use ssh to forward the X connection, and enable compression on this 16734) Use ssh to forward the X connection, and enable compression on this
1669 forwarded X connection (ssh -XC remotehostname emacs ...). 1674 forwarded X connection (ssh -XC remotehostname emacs ...).
1670 1675
16714) Use lbxproxy on the remote end of the connection. This is an interface 1676 Keep in mind that this does not help with latency problems, only
1672 to the low bandwidth X extension in most modern X servers, which 1677 andwidth ones.
1673 improves performance dramatically, at the slight expense of correctness 1678
1674 of the X protocol. lbxproxy achieves the performance gain by grouping 16795) Use lbxproxy on the remote end of the connection. This is an
1675 several X requests in one TCP packet and sending them off together, 1680 interface to the low bandwidth X extension in some outdated X
1676 instead of requiring a round-trip for each X request in a separate 1681 servers, which improves performance dramatically, at the slight
1677 packet. The switches that seem to work best for emacs are: 1682 expense of correctness of the X protocol. lbxproxy achieves the
1678 -noatomsfile -nowinattr -cheaterrors -cheatevents 1683 performance gain by grouping several X requests in one TCP packet
1679 Note that the -nograbcmap option is known to cause problems. 1684 and sending them off together, instead of requiring a round-trip
1680 For more about lbxproxy, see: 1685 for each X request in a separate packet. The switches that seem to
1686 work best for emacs are: -noatomsfile -nowinattr -cheaterrors
1687 -cheatevents Note that the -nograbcmap option is known to cause
1688 problems. For more about lbxproxy, see:
1681 http://www.x.org/archive/X11R6.8.0/doc/lbxproxy.1.html 1689 http://www.x.org/archive/X11R6.8.0/doc/lbxproxy.1.html
1682 1690
16835) If copying and killing is slow, try to disable the interaction with the 1691 Keep in mind that lbxproxy and the LBX extension are now obsolete.
1692
16936) If copying and killing is slow, try to disable the interaction with the
1684 native system's clipboard by adding these lines to your .emacs file: 1694 native system's clipboard by adding these lines to your .emacs file:
1695
1685 (setq interprogram-cut-function nil) 1696 (setq interprogram-cut-function nil)
1686 (setq interprogram-paste-function nil) 1697 (setq interprogram-paste-function nil)
1687 1698
16997) If selecting text with the mouse is slow, the main culprit is
1700 likely `select-active-regions', coupled with a program monitoring
1701 the clipboard on the X server you are connected to. Try turning
1702 that off.
1703
1704 However, over networks with moderate to high latency, with no
1705 clipboard monitor running, the bottleneck is likely to be
1706 `mouse-position' instead. Set the variable
1707 `x-use-fast-mouse-position' to either any non-nil value, or to the
1708 symbol `really-fast' if that is still too slow. Doing so will also
1709 cause Emacs features that relies on accurate mouse position
1710 reporting to stop working reliably.
1711
1688*** Emacs gives the error, Couldn't find per display information. 1712*** Emacs gives the error, Couldn't find per display information.
1689 1713
1690This can result if the X server runs out of memory because Emacs uses 1714This can result if the X server runs out of memory because Emacs uses
diff --git a/src/xterm.c b/src/xterm.c
index b17a7edba68..deedc595cb2 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -14261,8 +14261,113 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
14261 Time *timestamp) 14261 Time *timestamp)
14262{ 14262{
14263 struct frame *f1, *maybe_tooltip; 14263 struct frame *f1, *maybe_tooltip;
14264 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp); 14264 struct x_display_info *dpyinfo;
14265 bool unrelated_tooltip; 14265 bool unrelated_tooltip;
14266 Lisp_Object tail, frame;
14267
14268 dpyinfo = FRAME_DISPLAY_INFO (*fp);
14269
14270 if (!NILP (Vx_use_fast_mouse_position))
14271 {
14272 /* The user says that Emacs is running over the network, and a
14273 fast approximation of `mouse-position' should be used.
14274
14275 Depending on what the value of `x-use-fast-mouse-position'
14276 is, do one of two things: only perform the XQueryPointer to
14277 obtain the coordinates from the last mouse frame, or only
14278 return the last mouse motion frame and the
14279 last_mouse_motion_x and Y. */
14280
14281 if (!EQ (Vx_use_fast_mouse_position, Qreally_fast))
14282 {
14283 int root_x, root_y, win_x, win_y;
14284 unsigned int mask;
14285 Window dummy;
14286
14287 /* This means that Emacs should select a frame and report
14288 the mouse position relative to it. The approach used
14289 here avoids making multiple roundtrips to the X server
14290 querying for the window beneath the pointer, and was
14291 borrowed from haiku_mouse_position in haikuterm.c. */
14292
14293 FOR_EACH_FRAME (tail, frame)
14294 {
14295 if (FRAME_X_P (XFRAME (frame)))
14296 XFRAME (frame)->mouse_moved = false;
14297 }
14298
14299 if (gui_mouse_grabbed (dpyinfo)
14300 && !EQ (track_mouse, Qdropping)
14301 && !EQ (track_mouse, Qdrag_source))
14302 /* Pick the last mouse frame if dropping. */
14303 f1 = x_display_list->last_mouse_frame;
14304 else
14305 /* Otherwise, pick the last mouse motion frame. */
14306 f1 = x_display_list->last_mouse_motion_frame;
14307
14308 if (!f1 && FRAME_X_P (SELECTED_FRAME ()))
14309 f1 = SELECTED_FRAME ();
14310
14311 if (!f1 || (!FRAME_X_P (f1) && (insist > 0)))
14312 FOR_EACH_FRAME (tail, frame)
14313 if (FRAME_X_P (XFRAME (frame)) &&
14314 !FRAME_X_P (XFRAME (frame)))
14315 f1 = XFRAME (frame);
14316
14317 if (f1 && FRAME_TOOLTIP_P (f1))
14318 f1 = NULL;
14319
14320 if (f1 && FRAME_X_P (f1) && FRAME_X_WINDOW (f1))
14321 {
14322 if (!x_query_pointer (dpyinfo->display, FRAME_X_WINDOW (f1),
14323 &dummy, &dummy, &root_x, &root_y,
14324 &win_x, &win_y, &mask))
14325 /* The pointer is out of the screen. */
14326 return;
14327
14328 remember_mouse_glyph (f1, win_x, win_y,
14329 &dpyinfo->last_mouse_glyph);
14330 x_display_list->last_mouse_glyph_frame = f1;
14331
14332 *bar_window = Qnil;
14333 *part = scroll_bar_nowhere;
14334
14335 /* If track-mouse is `drag-source' and the mouse pointer is
14336 certain to not be actually under the chosen frame, return
14337 NULL in FP. */
14338 if (EQ (track_mouse, Qdrag_source)
14339 && (win_x < 0 || win_y < 0
14340 || win_x >= FRAME_PIXEL_WIDTH (f1)
14341 || win_y >= FRAME_PIXEL_HEIGHT (f1)))
14342 *fp = NULL;
14343 else
14344 *fp = f1;
14345
14346 *timestamp = dpyinfo->last_mouse_movement_time;
14347 XSETINT (*x, win_x);
14348 XSETINT (*y, win_y);
14349 }
14350 }
14351 else
14352 {
14353 /* This means Emacs should only report the coordinates of
14354 the last mouse motion. */
14355
14356 if (dpyinfo->last_mouse_motion_frame)
14357 {
14358 *fp = dpyinfo->last_mouse_motion_frame;
14359 *timestamp = dpyinfo->last_mouse_movement_time;
14360 *x = make_fixnum (dpyinfo->last_mouse_motion_x);
14361 *y = make_fixnum (dpyinfo->last_mouse_motion_y);
14362 *bar_window = Qnil;
14363 *part = scroll_bar_nowhere;
14364
14365 dpyinfo->last_mouse_motion_frame->mouse_moved = false;
14366 }
14367 }
14368
14369 return;
14370 }
14266 14371
14267 block_input (); 14372 block_input ();
14268 14373
@@ -31131,6 +31236,7 @@ With MS Windows, Haiku windowing or Nextstep, the value is t. */);
31131 DEFSYM (Qimitate_pager, "imitate-pager"); 31236 DEFSYM (Qimitate_pager, "imitate-pager");
31132 DEFSYM (Qnewer_time, "newer-time"); 31237 DEFSYM (Qnewer_time, "newer-time");
31133 DEFSYM (Qraise_and_focus, "raise-and-focus"); 31238 DEFSYM (Qraise_and_focus, "raise-and-focus");
31239 DEFSYM (Qreally_fast, "really-fast");
31134 31240
31135 DEFVAR_LISP ("x-ctrl-keysym", Vx_ctrl_keysym, 31241 DEFVAR_LISP ("x-ctrl-keysym", Vx_ctrl_keysym,
31136 doc: /* Which keys Emacs uses for the ctrl modifier. 31242 doc: /* Which keys Emacs uses for the ctrl modifier.
@@ -31410,4 +31516,19 @@ not bypass window manager focus stealing prevention):
31410 - The symbol `raise-and-focus', which means to raise the window and 31516 - The symbol `raise-and-focus', which means to raise the window and
31411 focus it manually. */); 31517 focus it manually. */);
31412 Vx_allow_focus_stealing = Qnewer_time; 31518 Vx_allow_focus_stealing = Qnewer_time;
31519
31520 DEFVAR_LISP ("x-use-fast-mouse-position", Vx_use_fast_mouse_position,
31521 doc: /* How to make `mouse-position' faster.
31522
31523`mouse-position' and `mouse-pixel-position' default to querying the X
31524server for the window under the mouse pointer. This results in
31525accurate results, but is also very slow when the X connection has
31526moderate to high latency. Setting this variable to a non-nil value
31527makes Emacs query only for the position of the pointer, which is
31528usually faster. Doing so improves the performance of dragging to
31529select text over slow X connections.
31530
31531If that is still too slow, setting this variable to the symbol
31532`really-fast' will make Emacs return only cached values. */);
31533 Vx_use_fast_mouse_position = Qnil;
31413} 31534}
diff --git a/src/xterm.h b/src/xterm.h
index b6ab42e72d2..c36920081d3 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -580,7 +580,9 @@ struct x_display_info
580 Time last_user_time; 580 Time last_user_time;
581 581
582 /* Position where the mouse was last time we reported a motion. 582 /* Position where the mouse was last time we reported a motion.
583 This is a position on last_mouse_motion_frame. */ 583 This is a position on last_mouse_motion_frame. It is used in
584 some situations to report the mouse position as well: see
585 XTmouse_position. */
584 int last_mouse_motion_x; 586 int last_mouse_motion_x;
585 int last_mouse_motion_y; 587 int last_mouse_motion_y;
586 588
@@ -1605,22 +1607,15 @@ SELECTION_EVENT_DISPLAY (struct selection_input_event *ev)
1605 1607
1606extern void x_free_gcs (struct frame *); 1608extern void x_free_gcs (struct frame *);
1607extern void x_relative_mouse_position (struct frame *, int *, int *); 1609extern void x_relative_mouse_position (struct frame *, int *, int *);
1608extern void x_real_pos_and_offsets (struct frame *f, 1610extern void x_real_pos_and_offsets (struct frame *, int *, int *, int *,
1609 int *left_offset_x, 1611 int *, int *, int *, int *, int *,
1610 int *right_offset_x, 1612 int *);
1611 int *top_offset_y,
1612 int *bottom_offset_y,
1613 int *x_pixels_diff,
1614 int *y_pixels_diff,
1615 int *xptr,
1616 int *yptr,
1617 int *outer_border);
1618extern void x_default_font_parameter (struct frame *, Lisp_Object); 1613extern void x_default_font_parameter (struct frame *, Lisp_Object);
1619 1614
1620/* From xrdb.c. */ 1615/* From xrdb.c. */
1621 1616
1622XrmDatabase x_load_resources (Display *, const char *, const char *, 1617extern XrmDatabase x_load_resources (Display *, const char *, const char *,
1623 const char *); 1618 const char *);
1624extern const char *x_get_string_resource (void *, const char *, const char *); 1619extern const char *x_get_string_resource (void *, const char *, const char *);
1625 1620
1626/* Defined in xterm.c */ 1621/* Defined in xterm.c */