Implement new option 'mouse-prefer-closest-glyph'

* src/dispnew.c (mouse_prefer_closest_glyph): New global
variable.
(buffer_posn_from_coords):
* src/xdisp.c (remember_mouse_glyph): Respect
'mouse_prefer_closest_glyph'.
(mouse_fine_grained_tracking): Update documentation to
include 'mouse_prefer_closest_glyph' effects.

* doc/lispref/commands.texi (Accessing Mouse): Update
documentation to say what the new option does when enabled.
* lisp/cus-start.el (standard): New user option
'mouse-prefer-closest-glyph'.
This commit is contained in:
Moritz Maxeiner 2023-07-22 16:55:07 +02:00 committed by Eli Zaretskii
parent af547c4bbe
commit 191aef4f61
4 changed files with 45 additions and 1 deletions

View file

@ -2756,6 +2756,16 @@ If @var{whole} is non-@code{nil}, the @var{x} coordinate is relative
to the entire window area including scroll bars, margins and fringes.
@end defun
@defopt mouse-prefer-closest-glyph
If this variable is non-@code{nil}, the @code{posn-point} of a mouse
position list will be set to the position of the glyph whose left most
position is closest to the mouse pointer, as opposed to the position of
the glyph underneath the mouse pointer itself. For example, if
@code{posn-at-x-y} is called with @var{x} set to @code{9}, which is
contained within a character of width 10 positioned at column 0, the
point saved within the mouse position list will be after that character.
@end defopt
@node Accessing Scroll
@subsection Accessing Scroll Bar Events
@cindex scroll bar events, data in

View file

@ -231,6 +231,7 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of
(inverse-video display boolean)
(visible-bell display boolean)
(no-redraw-on-reenter display boolean)
(mouse-prefer-closest-glyph display boolean)
;; doc.c
(text-quoting-style display

View file

@ -5636,6 +5636,15 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
argument is ZV to prevent move_it_in_display_line from matching
based on buffer positions. */
move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X);
if (mouse_prefer_closest_glyph)
{
int next_x = it.current_x + it.pixel_width;
int before_dx = to_x - it.current_x;
int after_dx = next_x - to_x;
if (before_dx > after_dx)
move_it_in_display_line (&it, ZV, next_x, MOVE_TO_X);
}
bidi_unshelve_cache (itdata, 0);
Fset_buffer (old_current_buffer);
@ -6813,6 +6822,15 @@ predicates which report frame's specific UI-related capabilities. */);
DEFVAR_BOOL ("cursor-in-echo-area", cursor_in_echo_area,
doc: /* Non-nil means put cursor in minibuffer, at end of any message there. */);
DEFVAR_BOOL ("mouse-prefer-closest-glyph", mouse_prefer_closest_glyph,
doc: /* Non-nil means mouse position lists are reported relative
to the glyph closest to their coordinates.
When non-nil, mouse position lists will be reported with their
`posn-point' set to the position of the glyph closest to the mouse
pointer, instead of the glyph immediately under. */);
mouse_prefer_closest_glyph = false;
DEFVAR_LISP ("glyph-table", Vglyph_table,
doc: /* Table defining how to output a glyph code to the frame.
If not nil, this is a vector indexed by glyph code to define the glyph.

View file

@ -2759,6 +2759,7 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
enum window_part part;
enum glyph_row_area area;
int x, y, width, height;
int original_gx;
if (mouse_fine_grained_tracking)
{
@ -2769,6 +2770,8 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
/* Try to determine frame pixel position and size of the glyph under
frame pixel coordinates X/Y on frame F. */
original_gx = gx;
if (window_resize_pixelwise)
{
width = height = 1;
@ -2984,6 +2987,15 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
gy += WINDOW_TOP_EDGE_Y (w);
store_rect:
if (mouse_prefer_closest_glyph)
{
int half_width = width / 2;
width = half_width;
int bisection = gx + half_width;
if (original_gx > bisection)
gx = bisection;
}
STORE_NATIVE_RECT (*rect, gx, gy, width, height);
/* Visible feedback for debugging. */
@ -37503,7 +37515,10 @@ may be more familiar to users. */);
DEFVAR_BOOL ("mouse-fine-grained-tracking", mouse_fine_grained_tracking,
doc: /* Non-nil for pixel-wise mouse-movement.
When nil, mouse-movement events will not be generated as long as the
mouse stays within the extent of a single glyph (except for images). */);
mouse stays within the extent of a single glyph (except for images).
When nil and mouse-prefer-closest-glyph is non-nil, mouse-movement
events will instead not be generated as long as the mouse stays within
the extent of a single left/right half glyph (except for images). */);
mouse_fine_grained_tracking = false;
DEFVAR_BOOL ("tab-bar--dragging-in-progress", tab_bar__dragging_in_progress,