* xterm.h (struct x_display_info): New members last_mouse_glyph_frame,
last_mouse_scroll_bar, last_mouse_glyph and last_mouse_movement_time, going to replace static variables below. Adjust comments. * xterm.c (last_mouse_glyph, last_mouse_glyph_frame) (last_mouse_scroll_bar, last_mouse_movement_time): Remove. (note_mouse_movement, XTmouse_position, x_scroll_bar_note_movement) (x_scroll_bar_report_motion, handle_one_xevent, syms_of_xterm): Related users changed. * w32term.h (struct w32_display_info): New members last_mouse_glyph_frame, last_mouse_scroll_bar, last_mouse_scroll_bar_pos, last_mouse_glyph and last_mouse_movement_time, going to replace static variables below. Adjust comments. * w32term.c (last_mouse_glyph_frame, last_mouse_scroll_bar) (last_mouse_scroll_bar_pos, last_mouse_glyph, last_mouse_movement_time): Remove. (note_mouse_movement, w32_mouse_position, w32_scroll_bar_handle_click) (x_scroll_bar_report_motion, syms_of_w32term): Related users changed. * nsterm.h (struct ns_display_info): New members last_mouse_glyph, last_mouse_movement_time and last_mouse_scroll_bar, going to replace static variables below. * nsterm.m (last_mouse_glyph, last_mouse_movement_time) (last_mouse_scroll_bar): Remove. (note_mouse_movement, ns_mouse_position, mouseMoved, mouseEntered) (mouseExited): Related users changed.
This commit is contained in:
parent
f754477379
commit
ced135ebdb
7 changed files with 185 additions and 166 deletions
|
@ -1,3 +1,30 @@
|
|||
2013-09-19 Dmitry Antipov <dmantipov@yandex.ru>
|
||||
|
||||
* xterm.h (struct x_display_info): New members last_mouse_glyph_frame,
|
||||
last_mouse_scroll_bar, last_mouse_glyph and last_mouse_movement_time,
|
||||
going to replace static variables below. Adjust comments.
|
||||
* xterm.c (last_mouse_glyph, last_mouse_glyph_frame)
|
||||
(last_mouse_scroll_bar, last_mouse_movement_time): Remove.
|
||||
(note_mouse_movement, XTmouse_position, x_scroll_bar_note_movement)
|
||||
(x_scroll_bar_report_motion, handle_one_xevent, syms_of_xterm):
|
||||
Related users changed.
|
||||
* w32term.h (struct w32_display_info): New members last_mouse_glyph_frame,
|
||||
last_mouse_scroll_bar, last_mouse_scroll_bar_pos, last_mouse_glyph and
|
||||
last_mouse_movement_time, going to replace static variables below.
|
||||
Adjust comments.
|
||||
* w32term.c (last_mouse_glyph_frame, last_mouse_scroll_bar)
|
||||
(last_mouse_scroll_bar_pos, last_mouse_glyph, last_mouse_movement_time):
|
||||
Remove.
|
||||
(note_mouse_movement, w32_mouse_position, w32_scroll_bar_handle_click)
|
||||
(x_scroll_bar_report_motion, syms_of_w32term): Related users changed.
|
||||
* nsterm.h (struct ns_display_info): New members last_mouse_glyph,
|
||||
last_mouse_movement_time and last_mouse_scroll_bar, going to replace
|
||||
static variables below.
|
||||
* nsterm.m (last_mouse_glyph, last_mouse_movement_time)
|
||||
(last_mouse_scroll_bar): Remove.
|
||||
(note_mouse_movement, ns_mouse_position, mouseMoved, mouseEntered)
|
||||
(mouseExited): Related users changed.
|
||||
|
||||
2013-09-19 Dmitry Antipov <dmantipov@yandex.ru>
|
||||
|
||||
Do not use external array to process X scroll bar messages.
|
||||
|
|
13
src/nsterm.h
13
src/nsterm.h
|
@ -608,6 +608,19 @@ struct ns_display_info
|
|||
This is a position on last_mouse_motion_frame. */
|
||||
int last_mouse_motion_x;
|
||||
int last_mouse_motion_y;
|
||||
|
||||
/* Where the mouse was last time we reported a mouse position. */
|
||||
NSRect last_mouse_glyph;
|
||||
|
||||
/* Time of last mouse movement. */
|
||||
Time last_mouse_movement_time;
|
||||
|
||||
/* The scroll bar in which the last motion event occurred. */
|
||||
#ifdef __OBJC__
|
||||
EmacsScroller *last_mouse_scroll_bar;
|
||||
#else
|
||||
void *last_mouse_scroll_bar;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* This is a chain of structures for all the NS displays currently in use. */
|
||||
|
|
49
src/nsterm.m
49
src/nsterm.m
|
@ -191,9 +191,6 @@ Updated by Christian Limpach (chris@nice.ch)
|
|||
long context_menu_value = 0;
|
||||
|
||||
/* display update */
|
||||
static NSRect last_mouse_glyph;
|
||||
static Time last_mouse_movement_time = 0;
|
||||
static EmacsScroller *last_mouse_scroll_bar = nil;
|
||||
static struct frame *ns_updating_frame;
|
||||
static NSView *focus_view = NULL;
|
||||
static int ns_window_num = 0;
|
||||
|
@ -1738,24 +1735,26 @@ Free a pool and temporary objects it refers to (callable from C)
|
|||
known as last_mouse_glyph.
|
||||
------------------------------------------------------------------------ */
|
||||
{
|
||||
struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame);
|
||||
NSRect *r;
|
||||
|
||||
// NSTRACE (note_mouse_movement);
|
||||
|
||||
FRAME_DISPLAY_INFO (frame)->last_mouse_motion_frame = frame;
|
||||
dpyinfo->last_mouse_motion_frame = frame;
|
||||
r = &dpyinfo->last_mouse_glyph;
|
||||
|
||||
/* Note, this doesn't get called for enter/leave, since we don't have a
|
||||
position. Those are taken care of in the corresponding NSView methods. */
|
||||
|
||||
/* has movement gone beyond last rect we were tracking? */
|
||||
if (x < last_mouse_glyph.origin.x ||
|
||||
x >= (last_mouse_glyph.origin.x + last_mouse_glyph.size.width) ||
|
||||
y < last_mouse_glyph.origin.y ||
|
||||
y >= (last_mouse_glyph.origin.y + last_mouse_glyph.size.height))
|
||||
if (x < r->origin.x || x >= r->origin.x + r->size.width
|
||||
|| y < r->origin.y || y >= r->origin.y + r->size.height)
|
||||
{
|
||||
ns_update_begin(frame);
|
||||
ns_update_begin (frame);
|
||||
frame->mouse_moved = 1;
|
||||
note_mouse_highlight (frame, x, y);
|
||||
remember_mouse_glyph (frame, x, y, &last_mouse_glyph);
|
||||
ns_update_end(frame);
|
||||
remember_mouse_glyph (frame, x, y, r);
|
||||
ns_update_end (frame);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1792,14 +1791,15 @@ Free a pool and temporary objects it refers to (callable from C)
|
|||
|
||||
block_input ();
|
||||
|
||||
if (last_mouse_scroll_bar != nil && insist == 0)
|
||||
if (dpyinfo->last_mouse_scroll_bar != nil && insist == 0)
|
||||
{
|
||||
/* TODO: we do not use this path at the moment because drag events will
|
||||
go directly to the EmacsScroller. Leaving code in for now. */
|
||||
[last_mouse_scroll_bar getMouseMotionPart: (int *)part window: bar_window
|
||||
x: x y: y];
|
||||
if (time) *time = last_mouse_movement_time;
|
||||
last_mouse_scroll_bar = nil;
|
||||
[dpyinfo->last_mouse_scroll_bar
|
||||
getMouseMotionPart: (int *)part window: bar_window x: x y: y];
|
||||
if (time)
|
||||
*time = dpyinfo->last_mouse_movement_time;
|
||||
dpyinfo->last_mouse_scroll_bar = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1809,7 +1809,7 @@ Free a pool and temporary objects it refers to (callable from C)
|
|||
&& FRAME_NS_DISPLAY (XFRAME (frame)) == FRAME_NS_DISPLAY (*fp))
|
||||
XFRAME (frame)->mouse_moved = 0;
|
||||
|
||||
last_mouse_scroll_bar = nil;
|
||||
dpyinfo->last_mouse_scroll_bar = nil;
|
||||
if (dpyinfo->last_mouse_frame
|
||||
&& FRAME_LIVE_P (dpyinfo->last_mouse_frame))
|
||||
f = dpyinfo->last_mouse_frame;
|
||||
|
@ -1823,7 +1823,8 @@ Free a pool and temporary objects it refers to (callable from C)
|
|||
|
||||
position = [[view window] mouseLocationOutsideOfEventStream];
|
||||
position = [view convertPoint: position fromView: nil];
|
||||
remember_mouse_glyph (f, position.x, position.y, &last_mouse_glyph);
|
||||
remember_mouse_glyph (f, position.x, position.y,
|
||||
&dpyinfo->last_mouse_glyph);
|
||||
/*fprintf (stderr, "ns_mouse_position: %.0f, %.0f\n", position.x, position.y); */
|
||||
|
||||
if (bar_window) *bar_window = Qnil;
|
||||
|
@ -1831,7 +1832,8 @@ Free a pool and temporary objects it refers to (callable from C)
|
|||
|
||||
if (x) XSETINT (*x, lrint (position.x));
|
||||
if (y) XSETINT (*y, lrint (position.y));
|
||||
if (time) *time = last_mouse_movement_time;
|
||||
if (time)
|
||||
*time = dpyinfo->last_mouse_movement_time;
|
||||
*fp = f;
|
||||
}
|
||||
}
|
||||
|
@ -5452,7 +5454,7 @@ - (void)mouseMoved: (NSEvent *)e
|
|||
|
||||
// NSTRACE (mouseMoved);
|
||||
|
||||
last_mouse_movement_time = EV_TIMESTAMP (e);
|
||||
dpyinfo->last_mouse_movement_time = EV_TIMESTAMP (e);
|
||||
pt = [self convertPoint: [e locationInWindow] fromView: nil];
|
||||
dpyinfo->last_mouse_motion_x = pt.x;
|
||||
dpyinfo->last_mouse_motion_y = pt.y;
|
||||
|
@ -6336,7 +6338,9 @@ - (void) setFSValue: (int)value
|
|||
- (void)mouseEntered: (NSEvent *)theEvent
|
||||
{
|
||||
NSTRACE (mouseEntered);
|
||||
last_mouse_movement_time = EV_TIMESTAMP (theEvent);
|
||||
if (emacsframe)
|
||||
FRAME_DISPLAY_INFO (emacsframe)->last_mouse_movement_time
|
||||
= EV_TIMESTAMP (theEvent);
|
||||
}
|
||||
|
||||
|
||||
|
@ -6349,7 +6353,8 @@ - (void)mouseExited: (NSEvent *)theEvent
|
|||
if (!hlinfo)
|
||||
return;
|
||||
|
||||
last_mouse_movement_time = EV_TIMESTAMP (theEvent);
|
||||
FRAME_DISPLAY_INFO (emacsframe)->last_mouse_movement_time
|
||||
= EV_TIMESTAMP (theEvent);
|
||||
|
||||
if (emacsframe == hlinfo->mouse_face_mouse_frame)
|
||||
{
|
||||
|
|
|
@ -171,31 +171,6 @@ int last_scroll_bar_drag_pos;
|
|||
/* Keyboard code page - may be changed by language-change events. */
|
||||
int w32_keyboard_codepage;
|
||||
|
||||
/* Mouse movement. */
|
||||
|
||||
/* Where the mouse was last time we reported a mouse event. */
|
||||
static RECT last_mouse_glyph;
|
||||
static struct frame *last_mouse_glyph_frame;
|
||||
|
||||
/* The scroll bar in which the last motion event occurred.
|
||||
|
||||
If the last motion event occurred in a scroll bar, we set this
|
||||
so w32_mouse_position can know whether to report a scroll bar motion or
|
||||
an ordinary motion.
|
||||
|
||||
If the last motion event didn't occur in a scroll bar, we set this
|
||||
to Qnil, to tell w32_mouse_position to return an ordinary motion event. */
|
||||
static Lisp_Object last_mouse_scroll_bar;
|
||||
static int last_mouse_scroll_bar_pos;
|
||||
|
||||
/* This is a hack. We would really prefer that w32_mouse_position would
|
||||
return the time associated with the position it returns, but there
|
||||
doesn't seem to be any way to wrest the time-stamp from the server
|
||||
along with the position query. So, we just keep track of the time
|
||||
of the last movement we received, and return that in hopes that
|
||||
it's somewhat accurate. */
|
||||
static Time last_mouse_movement_time;
|
||||
|
||||
/* Incremented by w32_read_socket whenever it really tries to read
|
||||
events. */
|
||||
static int volatile input_signal_count;
|
||||
|
@ -3310,12 +3285,13 @@ note_mouse_movement (struct frame *frame, MSG *msg)
|
|||
struct w32_display_info *dpyinfo;
|
||||
int mouse_x = LOWORD (msg->lParam);
|
||||
int mouse_y = HIWORD (msg->lParam);
|
||||
RECT *r;
|
||||
|
||||
if (!FRAME_X_OUTPUT (frame))
|
||||
return 0;
|
||||
|
||||
dpyinfo = FRAME_DISPLAY_INFO (frame);
|
||||
last_mouse_movement_time = msg->time;
|
||||
dpyinfo->last_mouse_movement_time = msg->time;
|
||||
dpyinfo->last_mouse_motion_frame = frame;
|
||||
dpyinfo->last_mouse_motion_x = mouse_x;
|
||||
dpyinfo->last_mouse_motion_y = mouse_y;
|
||||
|
@ -3323,28 +3299,27 @@ note_mouse_movement (struct frame *frame, MSG *msg)
|
|||
if (msg->hwnd != FRAME_W32_WINDOW (frame))
|
||||
{
|
||||
frame->mouse_moved = 1;
|
||||
last_mouse_scroll_bar = Qnil;
|
||||
dpyinfo->last_mouse_scroll_bar = NULL;
|
||||
note_mouse_highlight (frame, -1, -1);
|
||||
last_mouse_glyph_frame = 0;
|
||||
dpyinfo->last_mouse_glyph_frame = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Has the mouse moved off the glyph it was on at the last sighting? */
|
||||
if (frame != last_mouse_glyph_frame
|
||||
|| mouse_x < last_mouse_glyph.left
|
||||
|| mouse_x >= last_mouse_glyph.right
|
||||
|| mouse_y < last_mouse_glyph.top
|
||||
|| mouse_y >= last_mouse_glyph.bottom)
|
||||
r = &dpyinfo->last_mouse_glyph;
|
||||
if (frame != dpyinfo->last_mouse_glyph_frame
|
||||
|| mouse_x < r->left || mouse_x >= r->right
|
||||
|| mouse_y < r->top || mouse_y >= r->bottom)
|
||||
{
|
||||
frame->mouse_moved = 1;
|
||||
last_mouse_scroll_bar = Qnil;
|
||||
dpyinfo->last_mouse_scroll_bar = NULL;
|
||||
note_mouse_highlight (frame, mouse_x, mouse_y);
|
||||
/* Remember the mouse position here, as w32_mouse_position only
|
||||
gets called when mouse tracking is enabled but we also need
|
||||
to keep track of the mouse for help_echo and highlighting at
|
||||
other times. */
|
||||
remember_mouse_glyph (frame, mouse_x, mouse_y, &last_mouse_glyph);
|
||||
last_mouse_glyph_frame = frame;
|
||||
remember_mouse_glyph (frame, mouse_x, mouse_y, r);
|
||||
dpyinfo->last_mouse_glyph_frame = frame;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -3398,7 +3373,7 @@ w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
|
|||
|
||||
block_input ();
|
||||
|
||||
if (! NILP (last_mouse_scroll_bar) && insist == 0)
|
||||
if (dpyinfo->last_mouse_scroll_bar && insist == 0)
|
||||
x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
|
||||
else
|
||||
{
|
||||
|
@ -3410,7 +3385,7 @@ w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
|
|||
FOR_EACH_FRAME (tail, frame)
|
||||
XFRAME (frame)->mouse_moved = 0;
|
||||
|
||||
last_mouse_scroll_bar = Qnil;
|
||||
dpyinfo->last_mouse_scroll_bar = NULL;
|
||||
|
||||
GetCursorPos (&pt);
|
||||
|
||||
|
@ -3448,16 +3423,17 @@ w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
|
|||
on it, i.e. into the same rectangles that matrices on
|
||||
the frame are divided into. */
|
||||
|
||||
dpyinfo = FRAME_DISPLAY_INFO (f1);
|
||||
ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
|
||||
remember_mouse_glyph (f1, pt.x, pt.y, &last_mouse_glyph);
|
||||
last_mouse_glyph_frame = f1;
|
||||
remember_mouse_glyph (f1, pt.x, pt.y, &dpyinfo->last_mouse_glyph);
|
||||
dpyinfo->last_mouse_glyph_frame = f1;
|
||||
|
||||
*bar_window = Qnil;
|
||||
*part = 0;
|
||||
*fp = f1;
|
||||
XSETINT (*x, pt.x);
|
||||
XSETINT (*y, pt.y);
|
||||
*time = last_mouse_movement_time;
|
||||
*time = dpyinfo->last_mouse_movement_time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4005,6 +3981,7 @@ w32_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
|
|||
|
||||
{
|
||||
int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
|
||||
struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
|
||||
int y;
|
||||
int dragging = !NILP (bar->dragging);
|
||||
SCROLLINFO si;
|
||||
|
@ -4016,9 +3993,7 @@ w32_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
|
|||
y = si.nPos;
|
||||
|
||||
bar->dragging = Qnil;
|
||||
|
||||
|
||||
last_mouse_scroll_bar_pos = msg->msg.wParam;
|
||||
FRAME_DISPLAY_INFO (f)->last_mouse_scroll_bar_pos = msg->msg.wParam;
|
||||
|
||||
switch (LOWORD (msg->msg.wParam))
|
||||
{
|
||||
|
@ -4101,7 +4076,8 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
|
|||
Lisp_Object *x, Lisp_Object *y,
|
||||
unsigned long *time)
|
||||
{
|
||||
struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
|
||||
struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
|
||||
struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
|
||||
Window w = SCROLL_BAR_W32_WINDOW (bar);
|
||||
struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
|
||||
int pos;
|
||||
|
@ -4120,13 +4096,13 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
|
|||
pos = si.nPos;
|
||||
top_range = si.nMax - si.nPage + 1;
|
||||
|
||||
switch (LOWORD (last_mouse_scroll_bar_pos))
|
||||
switch (LOWORD (dpyinfo->last_mouse_scroll_bar_pos))
|
||||
{
|
||||
case SB_THUMBPOSITION:
|
||||
case SB_THUMBTRACK:
|
||||
*part = scroll_bar_handle;
|
||||
if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)) <= 0xffff)
|
||||
pos = HIWORD (last_mouse_scroll_bar_pos);
|
||||
pos = HIWORD (dpyinfo->last_mouse_scroll_bar_pos);
|
||||
break;
|
||||
case SB_LINEDOWN:
|
||||
*part = scroll_bar_handle;
|
||||
|
@ -4141,9 +4117,9 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
|
|||
XSETINT (*y, top_range);
|
||||
|
||||
f->mouse_moved = 0;
|
||||
last_mouse_scroll_bar = Qnil;
|
||||
dpyinfo->last_mouse_scroll_bar = NULL;
|
||||
|
||||
*time = last_mouse_movement_time;
|
||||
*time = dpyinfo->last_mouse_movement_time;
|
||||
|
||||
unblock_input ();
|
||||
}
|
||||
|
@ -6553,9 +6529,6 @@ syms_of_w32term (void)
|
|||
staticpro (&w32_display_name_list);
|
||||
w32_display_name_list = Qnil;
|
||||
|
||||
staticpro (&last_mouse_scroll_bar);
|
||||
last_mouse_scroll_bar = Qnil;
|
||||
|
||||
DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
|
||||
|
||||
DEFSYM (Qadded, "added");
|
||||
|
|
|
@ -189,10 +189,27 @@ struct w32_display_info
|
|||
/* The frame where the mouse was last time we reported a mouse motion. */
|
||||
struct frame *last_mouse_motion_frame;
|
||||
|
||||
/* The frame where the mouse was last time we reported a mouse position. */
|
||||
struct frame *last_mouse_glyph_frame;
|
||||
|
||||
/* Position where the mouse was last time we reported a motion.
|
||||
This is a position on last_mouse_motion_frame. */
|
||||
int last_mouse_motion_x;
|
||||
int last_mouse_motion_y;
|
||||
|
||||
/* Where the mouse was last time we reported a mouse position.
|
||||
This is a rectangle on last_mouse_glyph_frame. */
|
||||
RECT last_mouse_glyph;
|
||||
|
||||
/* The scroll bar in which the last motion event occurred. */
|
||||
struct scroll_bar *last_mouse_scroll_bar;
|
||||
|
||||
/* Mouse position on the scroll bar above.
|
||||
FIXME: shouldn't it be a member of struct scroll_bar? */
|
||||
int last_mouse_scroll_bar_pos;
|
||||
|
||||
/* Time of last mouse movement. */
|
||||
Time last_mouse_movement_time;
|
||||
};
|
||||
|
||||
/* This is a chain of structures for all the displays currently in use. */
|
||||
|
|
148
src/xterm.c
148
src/xterm.c
|
@ -172,52 +172,6 @@ static bool toolkit_scroll_bar_interaction;
|
|||
|
||||
static Time ignore_next_mouse_click_timeout;
|
||||
|
||||
/* Mouse movement.
|
||||
|
||||
Formerly, we used PointerMotionHintMask (in standard_event_mask)
|
||||
so that we would have to call XQueryPointer after each MotionNotify
|
||||
event to ask for another such event. However, this made mouse tracking
|
||||
slow, and there was a bug that made it eventually stop.
|
||||
|
||||
Simply asking for MotionNotify all the time seems to work better.
|
||||
|
||||
In order to avoid asking for motion events and then throwing most
|
||||
of them away or busy-polling the server for mouse positions, we ask
|
||||
the server for pointer motion hints. This means that we get only
|
||||
one event per group of mouse movements. "Groups" are delimited by
|
||||
other kinds of events (focus changes and button clicks, for
|
||||
example), or by XQueryPointer calls; when one of these happens, we
|
||||
get another MotionNotify event the next time the mouse moves. This
|
||||
is at least as efficient as getting motion events when mouse
|
||||
tracking is on, and I suspect only negligibly worse when tracking
|
||||
is off. */
|
||||
|
||||
/* Where the mouse was last time we reported a mouse event. */
|
||||
|
||||
static XRectangle last_mouse_glyph;
|
||||
static struct frame *last_mouse_glyph_frame;
|
||||
|
||||
/* The scroll bar in which the last X motion event occurred.
|
||||
|
||||
If the last X motion event occurred in a scroll bar, we set this so
|
||||
XTmouse_position can know whether to report a scroll bar motion or
|
||||
an ordinary motion.
|
||||
|
||||
If the last X motion event didn't occur in a scroll bar, we set
|
||||
this to Qnil, to tell XTmouse_position to return an ordinary motion
|
||||
event. */
|
||||
|
||||
static Lisp_Object last_mouse_scroll_bar;
|
||||
|
||||
/* This is a hack. We would really prefer that XTmouse_position would
|
||||
return the time associated with the position it returns, but there
|
||||
doesn't seem to be any way to wrest the time-stamp from the server
|
||||
along with the position query. So, we just keep track of the time
|
||||
of the last movement we received, and return that in hopes that
|
||||
it's somewhat accurate. */
|
||||
|
||||
static Time last_mouse_movement_time;
|
||||
|
||||
/* Incremented by XTread_socket whenever it really tries to read
|
||||
events. */
|
||||
|
||||
|
@ -3820,9 +3774,25 @@ x_get_keysym_name (int keysym)
|
|||
return value;
|
||||
}
|
||||
|
||||
/* Mouse clicks and mouse movement. Rah.
|
||||
|
||||
|
||||
/* Mouse clicks and mouse movement. Rah. */
|
||||
Formerly, we used PointerMotionHintMask (in standard_event_mask)
|
||||
so that we would have to call XQueryPointer after each MotionNotify
|
||||
event to ask for another such event. However, this made mouse tracking
|
||||
slow, and there was a bug that made it eventually stop.
|
||||
|
||||
Simply asking for MotionNotify all the time seems to work better.
|
||||
|
||||
In order to avoid asking for motion events and then throwing most
|
||||
of them away or busy-polling the server for mouse positions, we ask
|
||||
the server for pointer motion hints. This means that we get only
|
||||
one event per group of mouse movements. "Groups" are delimited by
|
||||
other kinds of events (focus changes and button clicks, for
|
||||
example), or by XQueryPointer calls; when one of these happens, we
|
||||
get another MotionNotify event the next time the mouse moves. This
|
||||
is at least as efficient as getting motion events when mouse
|
||||
tracking is on, and I suspect only negligibly worse when tracking
|
||||
is off. */
|
||||
|
||||
/* Prepare a mouse-event in *RESULT for placement in the input queue.
|
||||
|
||||
|
@ -3863,13 +3833,14 @@ construct_mouse_click (struct input_event *result,
|
|||
static int
|
||||
note_mouse_movement (struct frame *frame, const XMotionEvent *event)
|
||||
{
|
||||
XRectangle *r;
|
||||
struct x_display_info *dpyinfo;
|
||||
|
||||
if (!FRAME_X_OUTPUT (frame))
|
||||
return 0;
|
||||
|
||||
dpyinfo = FRAME_DISPLAY_INFO (frame);
|
||||
last_mouse_movement_time = event->time;
|
||||
dpyinfo->last_mouse_movement_time = event->time;
|
||||
dpyinfo->last_mouse_motion_frame = frame;
|
||||
dpyinfo->last_mouse_motion_x = event->x;
|
||||
dpyinfo->last_mouse_motion_y = event->y;
|
||||
|
@ -3877,26 +3848,25 @@ note_mouse_movement (struct frame *frame, const XMotionEvent *event)
|
|||
if (event->window != FRAME_X_WINDOW (frame))
|
||||
{
|
||||
frame->mouse_moved = 1;
|
||||
last_mouse_scroll_bar = Qnil;
|
||||
dpyinfo->last_mouse_scroll_bar = NULL;
|
||||
note_mouse_highlight (frame, -1, -1);
|
||||
last_mouse_glyph_frame = 0;
|
||||
dpyinfo->last_mouse_glyph_frame = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Has the mouse moved off the glyph it was on at the last sighting? */
|
||||
if (frame != last_mouse_glyph_frame
|
||||
|| event->x < last_mouse_glyph.x
|
||||
|| event->x >= last_mouse_glyph.x + last_mouse_glyph.width
|
||||
|| event->y < last_mouse_glyph.y
|
||||
|| event->y >= last_mouse_glyph.y + last_mouse_glyph.height)
|
||||
r = &dpyinfo->last_mouse_glyph;
|
||||
if (frame != dpyinfo->last_mouse_glyph_frame
|
||||
|| event->x < r->x || event->x >= r->x + r->width
|
||||
|| event->y < r->y || event->y >= r->y + r->height)
|
||||
{
|
||||
frame->mouse_moved = 1;
|
||||
last_mouse_scroll_bar = Qnil;
|
||||
dpyinfo->last_mouse_scroll_bar = NULL;
|
||||
note_mouse_highlight (frame, event->x, event->y);
|
||||
/* Remember which glyph we're now on. */
|
||||
remember_mouse_glyph (frame, event->x, event->y, &last_mouse_glyph);
|
||||
last_mouse_glyph_frame = frame;
|
||||
remember_mouse_glyph (frame, event->x, event->y, r);
|
||||
dpyinfo->last_mouse_glyph_frame = frame;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -3933,7 +3903,7 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
|
|||
|
||||
block_input ();
|
||||
|
||||
if (! NILP (last_mouse_scroll_bar) && insist == 0)
|
||||
if (dpyinfo->last_mouse_scroll_bar && insist == 0)
|
||||
x_scroll_bar_report_motion (fp, bar_window, part, x, y, timestamp);
|
||||
else
|
||||
{
|
||||
|
@ -3951,7 +3921,7 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
|
|||
&& FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp))
|
||||
XFRAME (frame)->mouse_moved = 0;
|
||||
|
||||
last_mouse_scroll_bar = Qnil;
|
||||
dpyinfo->last_mouse_scroll_bar = NULL;
|
||||
|
||||
/* Figure out which root window we're on. */
|
||||
XQueryPointer (FRAME_X_DISPLAY (*fp),
|
||||
|
@ -4101,15 +4071,17 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
|
|||
on it, i.e. into the same rectangles that matrices on
|
||||
the frame are divided into. */
|
||||
|
||||
remember_mouse_glyph (f1, win_x, win_y, &last_mouse_glyph);
|
||||
last_mouse_glyph_frame = f1;
|
||||
/* FIXME: what if F1 is not an X frame? */
|
||||
dpyinfo = FRAME_DISPLAY_INFO (f1);
|
||||
remember_mouse_glyph (f1, win_x, win_y, &dpyinfo->last_mouse_glyph);
|
||||
dpyinfo->last_mouse_glyph_frame = f1;
|
||||
|
||||
*bar_window = Qnil;
|
||||
*part = 0;
|
||||
*fp = f1;
|
||||
XSETINT (*x, win_x);
|
||||
XSETINT (*y, win_y);
|
||||
*timestamp = last_mouse_movement_time;
|
||||
*timestamp = dpyinfo->last_mouse_movement_time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5589,11 +5561,11 @@ x_scroll_bar_note_movement (struct scroll_bar *bar,
|
|||
const XMotionEvent *event)
|
||||
{
|
||||
struct frame *f = XFRAME (XWINDOW (bar->window)->frame);
|
||||
struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
|
||||
|
||||
last_mouse_movement_time = event->time;
|
||||
|
||||
dpyinfo->last_mouse_movement_time = event->time;
|
||||
dpyinfo->last_mouse_scroll_bar = bar;
|
||||
f->mouse_moved = 1;
|
||||
XSETVECTOR (last_mouse_scroll_bar, bar);
|
||||
|
||||
/* If we're dragging the bar, display it. */
|
||||
if (bar->dragging != -1)
|
||||
|
@ -5620,7 +5592,8 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
|
|||
enum scroll_bar_part *part, Lisp_Object *x,
|
||||
Lisp_Object *y, Time *timestamp)
|
||||
{
|
||||
struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
|
||||
struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
|
||||
struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
|
||||
Window w = bar->x_window;
|
||||
struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
|
||||
int win_x, win_y;
|
||||
|
@ -5632,22 +5605,19 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
|
|||
|
||||
/* Get the mouse's position relative to the scroll bar window, and
|
||||
report that. */
|
||||
if (! XQueryPointer (FRAME_X_DISPLAY (f), w,
|
||||
if (XQueryPointer (FRAME_X_DISPLAY (f), w,
|
||||
|
||||
/* Root, child, root x and root y. */
|
||||
&dummy_window, &dummy_window,
|
||||
&dummy_coord, &dummy_coord,
|
||||
/* Root, child, root x and root y. */
|
||||
&dummy_window, &dummy_window,
|
||||
&dummy_coord, &dummy_coord,
|
||||
|
||||
/* Position relative to scroll bar. */
|
||||
&win_x, &win_y,
|
||||
/* Position relative to scroll bar. */
|
||||
&win_x, &win_y,
|
||||
|
||||
/* Mouse buttons and modifier keys. */
|
||||
&dummy_mask))
|
||||
;
|
||||
else
|
||||
/* Mouse buttons and modifier keys. */
|
||||
&dummy_mask))
|
||||
{
|
||||
int top_range
|
||||
= VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
|
||||
int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
|
||||
|
||||
win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
|
||||
|
||||
|
@ -5675,11 +5645,10 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
|
|||
XSETINT (*y, top_range);
|
||||
|
||||
f->mouse_moved = 0;
|
||||
last_mouse_scroll_bar = Qnil;
|
||||
dpyinfo->last_mouse_scroll_bar = NULL;
|
||||
*timestamp = dpyinfo->last_mouse_movement_time;
|
||||
}
|
||||
|
||||
*timestamp = last_mouse_movement_time;
|
||||
|
||||
unblock_input ();
|
||||
}
|
||||
|
||||
|
@ -6644,8 +6613,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|
|||
#ifdef USE_GTK
|
||||
/* We may get an EnterNotify on the buttons in the toolbar. In that
|
||||
case we moved out of any highlighted area and need to note this. */
|
||||
if (!f && last_mouse_glyph_frame)
|
||||
note_mouse_movement (last_mouse_glyph_frame, &event->xmotion);
|
||||
if (!f && dpyinfo->last_mouse_glyph_frame)
|
||||
note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &event->xmotion);
|
||||
#endif
|
||||
goto OTHER;
|
||||
|
||||
|
@ -6677,8 +6646,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|
|||
}
|
||||
#ifdef USE_GTK
|
||||
/* See comment in EnterNotify above */
|
||||
else if (last_mouse_glyph_frame)
|
||||
note_mouse_movement (last_mouse_glyph_frame, &event->xmotion);
|
||||
else if (dpyinfo->last_mouse_glyph_frame)
|
||||
note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &event->xmotion);
|
||||
#endif
|
||||
goto OTHER;
|
||||
|
||||
|
@ -6827,7 +6796,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|
|||
bool tool_bar_p = 0;
|
||||
|
||||
memset (&compose_status, 0, sizeof (compose_status));
|
||||
last_mouse_glyph_frame = 0;
|
||||
dpyinfo->last_mouse_glyph_frame = NULL;
|
||||
dpyinfo->last_user_time = event->xbutton.time;
|
||||
|
||||
f = (x_mouse_grabbed (dpyinfo) ? dpyinfo->last_mouse_frame
|
||||
|
@ -10629,9 +10598,6 @@ syms_of_xterm (void)
|
|||
staticpro (&x_display_name_list);
|
||||
x_display_name_list = Qnil;
|
||||
|
||||
staticpro (&last_mouse_scroll_bar);
|
||||
last_mouse_scroll_bar = Qnil;
|
||||
|
||||
DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
|
||||
DEFSYM (Qlatin_1, "latin-1");
|
||||
|
||||
|
|
20
src/xterm.h
20
src/xterm.h
|
@ -305,12 +305,18 @@ struct x_display_info
|
|||
/* The frame waiting to be auto-raised in XTread_socket. */
|
||||
struct frame *x_pending_autoraise_frame;
|
||||
|
||||
/* The frame where the mouse was last time we reported a mouse event. */
|
||||
/* The frame where the mouse was last time we reported a ButtonPress event. */
|
||||
struct frame *last_mouse_frame;
|
||||
|
||||
/* The frame where the mouse was last time we reported a mouse position. */
|
||||
struct frame *last_mouse_glyph_frame;
|
||||
|
||||
/* The frame where the mouse was last time we reported a mouse motion. */
|
||||
struct frame *last_mouse_motion_frame;
|
||||
|
||||
/* The scroll bar in which the last X motion event occurred. */
|
||||
struct scroll_bar *last_mouse_scroll_bar;
|
||||
|
||||
/* Time of last user interaction as returned in X events on this display. */
|
||||
Time last_user_time;
|
||||
|
||||
|
@ -319,6 +325,18 @@ struct x_display_info
|
|||
int last_mouse_motion_x;
|
||||
int last_mouse_motion_y;
|
||||
|
||||
/* Where the mouse was last time we reported a mouse position.
|
||||
This is a rectangle on last_mouse_glyph_frame. */
|
||||
XRectangle last_mouse_glyph;
|
||||
|
||||
/* Time of last mouse movement on this display. This is a hack because
|
||||
we would really prefer that XTmouse_position would return the time
|
||||
associated with the position it returns, but there doesn't seem to be
|
||||
any way to wrest the time-stamp from the server along with the position
|
||||
query. So, we just keep track of the time of the last movement we
|
||||
received, and return that in hopes that it's somewhat accurate. */
|
||||
Time last_mouse_movement_time;
|
||||
|
||||
/* The gray pixmap. */
|
||||
Pixmap gray;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue