Fix various problems with mouse highlight on XI2 builds
* src/dispextern.h (reset_mouse_highlight): Fix coding style. * src/xterm.c (xi_position_changed): New functions. (xi_report_motion_window_clear, handle_one_xevent): Don't report motion events if the pixel position did not actually change. * src/xterm.h (struct xi_device_t): New fields `last_motion_window', `last_motion_x' and `last_motion_y'.
This commit is contained in:
parent
bc8141594d
commit
34686263b7
3 changed files with 87 additions and 13 deletions
|
|
@ -2874,18 +2874,17 @@ typedef struct {
|
|||
INLINE void
|
||||
reset_mouse_highlight (Mouse_HLInfo *hlinfo)
|
||||
{
|
||||
|
||||
hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
|
||||
hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
|
||||
hlinfo->mouse_face_mouse_x = hlinfo->mouse_face_mouse_y = 0;
|
||||
hlinfo->mouse_face_beg_x = hlinfo->mouse_face_end_x = 0;
|
||||
hlinfo->mouse_face_face_id = DEFAULT_FACE_ID;
|
||||
hlinfo->mouse_face_mouse_frame = NULL;
|
||||
hlinfo->mouse_face_window = Qnil;
|
||||
hlinfo->mouse_face_overlay = Qnil;
|
||||
hlinfo->mouse_face_past_end = false;
|
||||
hlinfo->mouse_face_hidden = false;
|
||||
hlinfo->mouse_face_defer = false;
|
||||
hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
|
||||
hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
|
||||
hlinfo->mouse_face_mouse_x = hlinfo->mouse_face_mouse_y = 0;
|
||||
hlinfo->mouse_face_beg_x = hlinfo->mouse_face_end_x = 0;
|
||||
hlinfo->mouse_face_face_id = DEFAULT_FACE_ID;
|
||||
hlinfo->mouse_face_mouse_frame = NULL;
|
||||
hlinfo->mouse_face_window = Qnil;
|
||||
hlinfo->mouse_face_overlay = Qnil;
|
||||
hlinfo->mouse_face_past_end = false;
|
||||
hlinfo->mouse_face_hidden = false;
|
||||
hlinfo->mouse_face_defer = false;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
|||
71
src/xterm.c
71
src/xterm.c
|
|
@ -12809,6 +12809,43 @@ xi_handle_interaction (struct x_display_info *dpyinfo,
|
|||
xi_handle_focus_change (dpyinfo);
|
||||
}
|
||||
|
||||
/* Return whether or not XEV actually represents a change in the
|
||||
position of the pointer on DEVICE, with respect to the last event
|
||||
received. This is necessary because the input extension reports
|
||||
motion events in very high resolution, while Emacs is only fast
|
||||
enough to process motion events aligned to the pixel grid. */
|
||||
|
||||
static bool
|
||||
xi_position_changed (struct xi_device_t *device, XIDeviceEvent *xev)
|
||||
{
|
||||
bool changed;
|
||||
|
||||
changed = true;
|
||||
|
||||
if (xev->event != device->last_motion_window)
|
||||
goto out;
|
||||
|
||||
if (lrint (xev->event_x) == device->last_motion_x
|
||||
&& lrint (xev->event_y) == device->last_motion_y)
|
||||
{
|
||||
changed = false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
device->last_motion_x = lrint (xev->event_x);
|
||||
device->last_motion_y = lrint (xev->event_y);
|
||||
device->last_motion_window = xev->event;
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static void
|
||||
xi_report_motion_window_clear (struct xi_device_t *device)
|
||||
{
|
||||
device->last_motion_window = None;
|
||||
}
|
||||
|
||||
#ifdef HAVE_XINPUT2_1
|
||||
|
||||
/* Look up a scroll valuator in DEVICE by NUMBER. */
|
||||
|
|
@ -20060,6 +20097,28 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XINPUT2
|
||||
if (f && dpyinfo->supports_xi2)
|
||||
{
|
||||
Mouse_HLInfo *hlinfo;
|
||||
|
||||
/* The input extension doesn't report motion events when
|
||||
the part of the window below the pointer changes. To
|
||||
avoid outdated information from keeping
|
||||
i.e. mouse-highlight at the wrong position after the
|
||||
frame is moved or resized, reset the mouse highlight
|
||||
and last_mouse_motion_frame. */
|
||||
|
||||
if (dpyinfo->last_mouse_motion_frame == f)
|
||||
dpyinfo->last_mouse_motion_frame = NULL;
|
||||
|
||||
hlinfo = MOUSE_HL_INFO (f);
|
||||
|
||||
if (hlinfo->mouse_face_mouse_frame == f)
|
||||
reset_mouse_highlight (hlinfo);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
if (x_dnd_in_progress
|
||||
|
|
@ -20713,7 +20772,10 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|
|||
|
||||
case XI_Leave:
|
||||
{
|
||||
XILeaveEvent *leave = (XILeaveEvent *) xi_event;
|
||||
XILeaveEvent *leave;
|
||||
struct xi_device_t *device;
|
||||
|
||||
leave = (XILeaveEvent *) xi_event;
|
||||
#ifdef USE_GTK
|
||||
struct xi_device_t *source;
|
||||
XMotionEvent ev;
|
||||
|
|
@ -20730,6 +20792,10 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|
|||
#ifdef USE_GTK
|
||||
source = xi_device_from_id (dpyinfo, leave->sourceid);
|
||||
#endif
|
||||
device = xi_device_from_id (dpyinfo, leave->deviceid);
|
||||
|
||||
if (device)
|
||||
xi_report_motion_window_clear (device);
|
||||
|
||||
/* This allows us to catch LeaveNotify events generated by
|
||||
popup menu grabs. FIXME: this is right when there is a
|
||||
|
|
@ -21149,6 +21215,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|
|||
#endif
|
||||
#endif /* HAVE_XINPUT2_1 */
|
||||
|
||||
if (!xi_position_changed (device, xev))
|
||||
goto XI_OTHER;
|
||||
|
||||
ev.x = lrint (xev->event_x);
|
||||
ev.y = lrint (xev->event_y);
|
||||
ev.window = xev->event;
|
||||
|
|
|
|||
|
|
@ -286,6 +286,12 @@ struct xi_device_t
|
|||
/* The frame that is currently this device's implicit keyboard
|
||||
focus, or NULL. */
|
||||
struct frame *focus_implicit_frame;
|
||||
|
||||
/* The window on which the last motion event happened. */
|
||||
Window last_motion_window;
|
||||
|
||||
/* The rounded integer coordinates of the last motion event. */
|
||||
int last_motion_x, last_motion_y;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue