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.
This commit is contained in:
parent
682b068ba7
commit
32e29afe64
3 changed files with 170 additions and 30 deletions
56
etc/PROBLEMS
56
etc/PROBLEMS
|
@ -1640,16 +1640,21 @@ X expects to find it.
|
|||
|
||||
*** Improving performance with slow X connections.
|
||||
|
||||
There are several ways to improve this performance, any subset of which can
|
||||
be carried out at the same time:
|
||||
There are several ways to improve this performance, any subset of
|
||||
which can be carried out at the same time:
|
||||
|
||||
1) If you don't need X Input Methods (XIM) for entering text in some
|
||||
1) Use the "--with-x-toolkit=no" build of Emacs. By not relying on
|
||||
any toolkit (exhibiting potentially slow behavior), it has been
|
||||
made very fast over networks exhibiting high latency, but suitable
|
||||
bandwidth.
|
||||
|
||||
2) If you don't need X Input Methods (XIM) for entering text in some
|
||||
language you use, you can improve performance on WAN links by using
|
||||
the X resource useXIM to turn off use of XIM. This does not affect
|
||||
the use of Emacs's own input methods, which are part of the Leim
|
||||
package.
|
||||
|
||||
2) If the connection is very slow, you might also want to consider
|
||||
3) If the connection is very slow, you might also want to consider
|
||||
switching off scroll bars, menu bar, and tool bar. Adding the
|
||||
following forms to your .emacs file will accomplish that, but only
|
||||
after the initial frame is displayed:
|
||||
|
@ -1665,26 +1670,45 @@ be carried out at the same time:
|
|||
Emacs.menuBar: off
|
||||
Emacs.toolBar: off
|
||||
|
||||
3) Use ssh to forward the X connection, and enable compression on this
|
||||
4) Use ssh to forward the X connection, and enable compression on this
|
||||
forwarded X connection (ssh -XC remotehostname emacs ...).
|
||||
|
||||
4) Use lbxproxy on the remote end of the connection. This is an interface
|
||||
to the low bandwidth X extension in most modern X servers, which
|
||||
improves performance dramatically, at the slight expense of correctness
|
||||
of the X protocol. lbxproxy achieves the performance gain by grouping
|
||||
several X requests in one TCP packet and sending them off together,
|
||||
instead of requiring a round-trip for each X request in a separate
|
||||
packet. The switches that seem to work best for emacs are:
|
||||
-noatomsfile -nowinattr -cheaterrors -cheatevents
|
||||
Note that the -nograbcmap option is known to cause problems.
|
||||
For more about lbxproxy, see:
|
||||
Keep in mind that this does not help with latency problems, only
|
||||
andwidth ones.
|
||||
|
||||
5) Use lbxproxy on the remote end of the connection. This is an
|
||||
interface to the low bandwidth X extension in some outdated X
|
||||
servers, which improves performance dramatically, at the slight
|
||||
expense of correctness of the X protocol. lbxproxy achieves the
|
||||
performance gain by grouping several X requests in one TCP packet
|
||||
and sending them off together, instead of requiring a round-trip
|
||||
for each X request in a separate packet. The switches that seem to
|
||||
work best for emacs are: -noatomsfile -nowinattr -cheaterrors
|
||||
-cheatevents Note that the -nograbcmap option is known to cause
|
||||
problems. For more about lbxproxy, see:
|
||||
http://www.x.org/archive/X11R6.8.0/doc/lbxproxy.1.html
|
||||
|
||||
5) If copying and killing is slow, try to disable the interaction with the
|
||||
Keep in mind that lbxproxy and the LBX extension are now obsolete.
|
||||
|
||||
6) If copying and killing is slow, try to disable the interaction with the
|
||||
native system's clipboard by adding these lines to your .emacs file:
|
||||
|
||||
(setq interprogram-cut-function nil)
|
||||
(setq interprogram-paste-function nil)
|
||||
|
||||
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.
|
||||
|
||||
However, over networks with moderate to high latency, with no
|
||||
clipboard monitor running, the bottleneck is likely to be
|
||||
`mouse-position' instead. Set the variable
|
||||
`x-use-fast-mouse-position' to either any non-nil value, or to the
|
||||
symbol `really-fast' if that is still too slow. Doing so will also
|
||||
cause Emacs features that relies on accurate mouse position
|
||||
reporting to stop working reliably.
|
||||
|
||||
*** Emacs gives the error, Couldn't find per display information.
|
||||
|
||||
This can result if the X server runs out of memory because Emacs uses
|
||||
|
|
123
src/xterm.c
123
src/xterm.c
|
@ -14261,8 +14261,113 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
|
|||
Time *timestamp)
|
||||
{
|
||||
struct frame *f1, *maybe_tooltip;
|
||||
struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
|
||||
struct x_display_info *dpyinfo;
|
||||
bool unrelated_tooltip;
|
||||
Lisp_Object tail, frame;
|
||||
|
||||
dpyinfo = FRAME_DISPLAY_INFO (*fp);
|
||||
|
||||
if (!NILP (Vx_use_fast_mouse_position))
|
||||
{
|
||||
/* The user says that Emacs is running over the network, and a
|
||||
fast approximation of `mouse-position' should be used.
|
||||
|
||||
Depending on what the value of `x-use-fast-mouse-position'
|
||||
is, do one of two things: only perform the XQueryPointer to
|
||||
obtain the coordinates from the last mouse frame, or only
|
||||
return the last mouse motion frame and the
|
||||
last_mouse_motion_x and Y. */
|
||||
|
||||
if (!EQ (Vx_use_fast_mouse_position, Qreally_fast))
|
||||
{
|
||||
int root_x, root_y, win_x, win_y;
|
||||
unsigned int mask;
|
||||
Window dummy;
|
||||
|
||||
/* This means that Emacs should select a frame and report
|
||||
the mouse position relative to it. The approach used
|
||||
here avoids making multiple roundtrips to the X server
|
||||
querying for the window beneath the pointer, and was
|
||||
borrowed from haiku_mouse_position in haikuterm.c. */
|
||||
|
||||
FOR_EACH_FRAME (tail, frame)
|
||||
{
|
||||
if (FRAME_X_P (XFRAME (frame)))
|
||||
XFRAME (frame)->mouse_moved = false;
|
||||
}
|
||||
|
||||
if (gui_mouse_grabbed (dpyinfo)
|
||||
&& !EQ (track_mouse, Qdropping)
|
||||
&& !EQ (track_mouse, Qdrag_source))
|
||||
/* Pick the last mouse frame if dropping. */
|
||||
f1 = x_display_list->last_mouse_frame;
|
||||
else
|
||||
/* Otherwise, pick the last mouse motion frame. */
|
||||
f1 = x_display_list->last_mouse_motion_frame;
|
||||
|
||||
if (!f1 && FRAME_X_P (SELECTED_FRAME ()))
|
||||
f1 = SELECTED_FRAME ();
|
||||
|
||||
if (!f1 || (!FRAME_X_P (f1) && (insist > 0)))
|
||||
FOR_EACH_FRAME (tail, frame)
|
||||
if (FRAME_X_P (XFRAME (frame)) &&
|
||||
!FRAME_X_P (XFRAME (frame)))
|
||||
f1 = XFRAME (frame);
|
||||
|
||||
if (f1 && FRAME_TOOLTIP_P (f1))
|
||||
f1 = NULL;
|
||||
|
||||
if (f1 && FRAME_X_P (f1) && FRAME_X_WINDOW (f1))
|
||||
{
|
||||
if (!x_query_pointer (dpyinfo->display, FRAME_X_WINDOW (f1),
|
||||
&dummy, &dummy, &root_x, &root_y,
|
||||
&win_x, &win_y, &mask))
|
||||
/* The pointer is out of the screen. */
|
||||
return;
|
||||
|
||||
remember_mouse_glyph (f1, win_x, win_y,
|
||||
&dpyinfo->last_mouse_glyph);
|
||||
x_display_list->last_mouse_glyph_frame = f1;
|
||||
|
||||
*bar_window = Qnil;
|
||||
*part = scroll_bar_nowhere;
|
||||
|
||||
/* If track-mouse is `drag-source' and the mouse pointer is
|
||||
certain to not be actually under the chosen frame, return
|
||||
NULL in FP. */
|
||||
if (EQ (track_mouse, Qdrag_source)
|
||||
&& (win_x < 0 || win_y < 0
|
||||
|| win_x >= FRAME_PIXEL_WIDTH (f1)
|
||||
|| win_y >= FRAME_PIXEL_HEIGHT (f1)))
|
||||
*fp = NULL;
|
||||
else
|
||||
*fp = f1;
|
||||
|
||||
*timestamp = dpyinfo->last_mouse_movement_time;
|
||||
XSETINT (*x, win_x);
|
||||
XSETINT (*y, win_y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This means Emacs should only report the coordinates of
|
||||
the last mouse motion. */
|
||||
|
||||
if (dpyinfo->last_mouse_motion_frame)
|
||||
{
|
||||
*fp = dpyinfo->last_mouse_motion_frame;
|
||||
*timestamp = dpyinfo->last_mouse_movement_time;
|
||||
*x = make_fixnum (dpyinfo->last_mouse_motion_x);
|
||||
*y = make_fixnum (dpyinfo->last_mouse_motion_y);
|
||||
*bar_window = Qnil;
|
||||
*part = scroll_bar_nowhere;
|
||||
|
||||
dpyinfo->last_mouse_motion_frame->mouse_moved = false;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
block_input ();
|
||||
|
||||
|
@ -31131,6 +31236,7 @@ With MS Windows, Haiku windowing or Nextstep, the value is t. */);
|
|||
DEFSYM (Qimitate_pager, "imitate-pager");
|
||||
DEFSYM (Qnewer_time, "newer-time");
|
||||
DEFSYM (Qraise_and_focus, "raise-and-focus");
|
||||
DEFSYM (Qreally_fast, "really-fast");
|
||||
|
||||
DEFVAR_LISP ("x-ctrl-keysym", Vx_ctrl_keysym,
|
||||
doc: /* Which keys Emacs uses for the ctrl modifier.
|
||||
|
@ -31410,4 +31516,19 @@ not bypass window manager focus stealing prevention):
|
|||
- The symbol `raise-and-focus', which means to raise the window and
|
||||
focus it manually. */);
|
||||
Vx_allow_focus_stealing = Qnewer_time;
|
||||
|
||||
DEFVAR_LISP ("x-use-fast-mouse-position", Vx_use_fast_mouse_position,
|
||||
doc: /* How to make `mouse-position' faster.
|
||||
|
||||
`mouse-position' and `mouse-pixel-position' default to querying the X
|
||||
server for the window under the mouse pointer. This results in
|
||||
accurate results, but is also very slow when the X connection has
|
||||
moderate to high latency. Setting this variable to a non-nil value
|
||||
makes Emacs query only for the position of the pointer, which is
|
||||
usually faster. Doing so improves the performance of dragging to
|
||||
select text over slow X connections.
|
||||
|
||||
If that is still too slow, setting this variable to the symbol
|
||||
`really-fast' will make Emacs return only cached values. */);
|
||||
Vx_use_fast_mouse_position = Qnil;
|
||||
}
|
||||
|
|
21
src/xterm.h
21
src/xterm.h
|
@ -580,7 +580,9 @@ struct x_display_info
|
|||
Time last_user_time;
|
||||
|
||||
/* Position where the mouse was last time we reported a motion.
|
||||
This is a position on last_mouse_motion_frame. */
|
||||
This is a position on last_mouse_motion_frame. It is used in
|
||||
some situations to report the mouse position as well: see
|
||||
XTmouse_position. */
|
||||
int last_mouse_motion_x;
|
||||
int last_mouse_motion_y;
|
||||
|
||||
|
@ -1605,22 +1607,15 @@ SELECTION_EVENT_DISPLAY (struct selection_input_event *ev)
|
|||
|
||||
extern void x_free_gcs (struct frame *);
|
||||
extern void x_relative_mouse_position (struct frame *, int *, int *);
|
||||
extern void x_real_pos_and_offsets (struct frame *f,
|
||||
int *left_offset_x,
|
||||
int *right_offset_x,
|
||||
int *top_offset_y,
|
||||
int *bottom_offset_y,
|
||||
int *x_pixels_diff,
|
||||
int *y_pixels_diff,
|
||||
int *xptr,
|
||||
int *yptr,
|
||||
int *outer_border);
|
||||
extern void x_real_pos_and_offsets (struct frame *, int *, int *, int *,
|
||||
int *, int *, int *, int *, int *,
|
||||
int *);
|
||||
extern void x_default_font_parameter (struct frame *, Lisp_Object);
|
||||
|
||||
/* From xrdb.c. */
|
||||
|
||||
XrmDatabase x_load_resources (Display *, const char *, const char *,
|
||||
const char *);
|
||||
extern XrmDatabase x_load_resources (Display *, const char *, const char *,
|
||||
const char *);
|
||||
extern const char *x_get_string_resource (void *, const char *, const char *);
|
||||
|
||||
/* Defined in xterm.c */
|
||||
|
|
Loading…
Add table
Reference in a new issue