aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Antipov2013-09-19 11:48:53 +0400
committerDmitry Antipov2013-09-19 11:48:53 +0400
commitced135ebdbfb0eea719ce165a454e7ff0b681e88 (patch)
tree17311f84267e23afbd4d1131ea2fe1fa14aa6f55
parentf75447737926fd8c898b9e0b77f581f4993a52f1 (diff)
downloademacs-ced135ebdbfb0eea719ce165a454e7ff0b681e88.tar.gz
emacs-ced135ebdbfb0eea719ce165a454e7ff0b681e88.zip
* 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.
-rw-r--r--src/ChangeLog27
-rw-r--r--src/nsterm.h13
-rw-r--r--src/nsterm.m49
-rw-r--r--src/w32term.c77
-rw-r--r--src/w32term.h17
-rw-r--r--src/xterm.c148
-rw-r--r--src/xterm.h20
7 files changed, 185 insertions, 166 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 2a931693f62..d900818231e 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,32 @@
12013-09-19 Dmitry Antipov <dmantipov@yandex.ru> 12013-09-19 Dmitry Antipov <dmantipov@yandex.ru>
2 2
3 * xterm.h (struct x_display_info): New members last_mouse_glyph_frame,
4 last_mouse_scroll_bar, last_mouse_glyph and last_mouse_movement_time,
5 going to replace static variables below. Adjust comments.
6 * xterm.c (last_mouse_glyph, last_mouse_glyph_frame)
7 (last_mouse_scroll_bar, last_mouse_movement_time): Remove.
8 (note_mouse_movement, XTmouse_position, x_scroll_bar_note_movement)
9 (x_scroll_bar_report_motion, handle_one_xevent, syms_of_xterm):
10 Related users changed.
11 * w32term.h (struct w32_display_info): New members last_mouse_glyph_frame,
12 last_mouse_scroll_bar, last_mouse_scroll_bar_pos, last_mouse_glyph and
13 last_mouse_movement_time, going to replace static variables below.
14 Adjust comments.
15 * w32term.c (last_mouse_glyph_frame, last_mouse_scroll_bar)
16 (last_mouse_scroll_bar_pos, last_mouse_glyph, last_mouse_movement_time):
17 Remove.
18 (note_mouse_movement, w32_mouse_position, w32_scroll_bar_handle_click)
19 (x_scroll_bar_report_motion, syms_of_w32term): Related users changed.
20 * nsterm.h (struct ns_display_info): New members last_mouse_glyph,
21 last_mouse_movement_time and last_mouse_scroll_bar, going to replace
22 static variables below.
23 * nsterm.m (last_mouse_glyph, last_mouse_movement_time)
24 (last_mouse_scroll_bar): Remove.
25 (note_mouse_movement, ns_mouse_position, mouseMoved, mouseEntered)
26 (mouseExited): Related users changed.
27
282013-09-19 Dmitry Antipov <dmantipov@yandex.ru>
29
3 Do not use external array to process X scroll bar messages. 30 Do not use external array to process X scroll bar messages.
4 * xterm.c (scroll_bar_windows, scroll_bar_windows_size): Remove. 31 * xterm.c (scroll_bar_windows, scroll_bar_windows_size): Remove.
5 (x_send_scroll_bar_event): Pack window pointer into two slots 32 (x_send_scroll_bar_event): Pack window pointer into two slots
diff --git a/src/nsterm.h b/src/nsterm.h
index 7a626c75fe6..9f7767b312e 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -608,6 +608,19 @@ struct ns_display_info
608 This is a position on last_mouse_motion_frame. */ 608 This is a position on last_mouse_motion_frame. */
609 int last_mouse_motion_x; 609 int last_mouse_motion_x;
610 int last_mouse_motion_y; 610 int last_mouse_motion_y;
611
612 /* Where the mouse was last time we reported a mouse position. */
613 NSRect last_mouse_glyph;
614
615 /* Time of last mouse movement. */
616 Time last_mouse_movement_time;
617
618 /* The scroll bar in which the last motion event occurred. */
619#ifdef __OBJC__
620 EmacsScroller *last_mouse_scroll_bar;
621#else
622 void *last_mouse_scroll_bar;
623#endif
611}; 624};
612 625
613/* This is a chain of structures for all the NS displays currently in use. */ 626/* This is a chain of structures for all the NS displays currently in use. */
diff --git a/src/nsterm.m b/src/nsterm.m
index dc27fd09e30..5c9800f5416 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -191,9 +191,6 @@ Lisp_Object ns_display_name_list;
191long context_menu_value = 0; 191long context_menu_value = 0;
192 192
193/* display update */ 193/* display update */
194static NSRect last_mouse_glyph;
195static Time last_mouse_movement_time = 0;
196static EmacsScroller *last_mouse_scroll_bar = nil;
197static struct frame *ns_updating_frame; 194static struct frame *ns_updating_frame;
198static NSView *focus_view = NULL; 195static NSView *focus_view = NULL;
199static int ns_window_num = 0; 196static int ns_window_num = 0;
@@ -1738,24 +1735,26 @@ note_mouse_movement (struct frame *frame, CGFloat x, CGFloat y)
1738 known as last_mouse_glyph. 1735 known as last_mouse_glyph.
1739 ------------------------------------------------------------------------ */ 1736 ------------------------------------------------------------------------ */
1740{ 1737{
1738 struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame);
1739 NSRect *r;
1740
1741// NSTRACE (note_mouse_movement); 1741// NSTRACE (note_mouse_movement);
1742 1742
1743 FRAME_DISPLAY_INFO (frame)->last_mouse_motion_frame = frame; 1743 dpyinfo->last_mouse_motion_frame = frame;
1744 r = &dpyinfo->last_mouse_glyph;
1744 1745
1745 /* Note, this doesn't get called for enter/leave, since we don't have a 1746 /* Note, this doesn't get called for enter/leave, since we don't have a
1746 position. Those are taken care of in the corresponding NSView methods. */ 1747 position. Those are taken care of in the corresponding NSView methods. */
1747 1748
1748 /* has movement gone beyond last rect we were tracking? */ 1749 /* has movement gone beyond last rect we were tracking? */
1749 if (x < last_mouse_glyph.origin.x || 1750 if (x < r->origin.x || x >= r->origin.x + r->size.width
1750 x >= (last_mouse_glyph.origin.x + last_mouse_glyph.size.width) || 1751 || y < r->origin.y || y >= r->origin.y + r->size.height)
1751 y < last_mouse_glyph.origin.y ||
1752 y >= (last_mouse_glyph.origin.y + last_mouse_glyph.size.height))
1753 { 1752 {
1754 ns_update_begin(frame); 1753 ns_update_begin (frame);
1755 frame->mouse_moved = 1; 1754 frame->mouse_moved = 1;
1756 note_mouse_highlight (frame, x, y); 1755 note_mouse_highlight (frame, x, y);
1757 remember_mouse_glyph (frame, x, y, &last_mouse_glyph); 1756 remember_mouse_glyph (frame, x, y, r);
1758 ns_update_end(frame); 1757 ns_update_end (frame);
1759 return 1; 1758 return 1;
1760 } 1759 }
1761 1760
@@ -1792,14 +1791,15 @@ ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
1792 1791
1793 block_input (); 1792 block_input ();
1794 1793
1795 if (last_mouse_scroll_bar != nil && insist == 0) 1794 if (dpyinfo->last_mouse_scroll_bar != nil && insist == 0)
1796 { 1795 {
1797 /* TODO: we do not use this path at the moment because drag events will 1796 /* TODO: we do not use this path at the moment because drag events will
1798 go directly to the EmacsScroller. Leaving code in for now. */ 1797 go directly to the EmacsScroller. Leaving code in for now. */
1799 [last_mouse_scroll_bar getMouseMotionPart: (int *)part window: bar_window 1798 [dpyinfo->last_mouse_scroll_bar
1800 x: x y: y]; 1799 getMouseMotionPart: (int *)part window: bar_window x: x y: y];
1801 if (time) *time = last_mouse_movement_time; 1800 if (time)
1802 last_mouse_scroll_bar = nil; 1801 *time = dpyinfo->last_mouse_movement_time;
1802 dpyinfo->last_mouse_scroll_bar = nil;
1803 } 1803 }
1804 else 1804 else
1805 { 1805 {
@@ -1809,7 +1809,7 @@ ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
1809 && FRAME_NS_DISPLAY (XFRAME (frame)) == FRAME_NS_DISPLAY (*fp)) 1809 && FRAME_NS_DISPLAY (XFRAME (frame)) == FRAME_NS_DISPLAY (*fp))
1810 XFRAME (frame)->mouse_moved = 0; 1810 XFRAME (frame)->mouse_moved = 0;
1811 1811
1812 last_mouse_scroll_bar = nil; 1812 dpyinfo->last_mouse_scroll_bar = nil;
1813 if (dpyinfo->last_mouse_frame 1813 if (dpyinfo->last_mouse_frame
1814 && FRAME_LIVE_P (dpyinfo->last_mouse_frame)) 1814 && FRAME_LIVE_P (dpyinfo->last_mouse_frame))
1815 f = dpyinfo->last_mouse_frame; 1815 f = dpyinfo->last_mouse_frame;
@@ -1823,7 +1823,8 @@ ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
1823 1823
1824 position = [[view window] mouseLocationOutsideOfEventStream]; 1824 position = [[view window] mouseLocationOutsideOfEventStream];
1825 position = [view convertPoint: position fromView: nil]; 1825 position = [view convertPoint: position fromView: nil];
1826 remember_mouse_glyph (f, position.x, position.y, &last_mouse_glyph); 1826 remember_mouse_glyph (f, position.x, position.y,
1827 &dpyinfo->last_mouse_glyph);
1827/*fprintf (stderr, "ns_mouse_position: %.0f, %.0f\n", position.x, position.y); */ 1828/*fprintf (stderr, "ns_mouse_position: %.0f, %.0f\n", position.x, position.y); */
1828 1829
1829 if (bar_window) *bar_window = Qnil; 1830 if (bar_window) *bar_window = Qnil;
@@ -1831,7 +1832,8 @@ ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
1831 1832
1832 if (x) XSETINT (*x, lrint (position.x)); 1833 if (x) XSETINT (*x, lrint (position.x));
1833 if (y) XSETINT (*y, lrint (position.y)); 1834 if (y) XSETINT (*y, lrint (position.y));
1834 if (time) *time = last_mouse_movement_time; 1835 if (time)
1836 *time = dpyinfo->last_mouse_movement_time;
1835 *fp = f; 1837 *fp = f;
1836 } 1838 }
1837 } 1839 }
@@ -5452,7 +5454,7 @@ not_in_argv (NSString *arg)
5452 5454
5453// NSTRACE (mouseMoved); 5455// NSTRACE (mouseMoved);
5454 5456
5455 last_mouse_movement_time = EV_TIMESTAMP (e); 5457 dpyinfo->last_mouse_movement_time = EV_TIMESTAMP (e);
5456 pt = [self convertPoint: [e locationInWindow] fromView: nil]; 5458 pt = [self convertPoint: [e locationInWindow] fromView: nil];
5457 dpyinfo->last_mouse_motion_x = pt.x; 5459 dpyinfo->last_mouse_motion_x = pt.x;
5458 dpyinfo->last_mouse_motion_y = pt.y; 5460 dpyinfo->last_mouse_motion_y = pt.y;
@@ -6336,7 +6338,9 @@ if (cols > 0 && rows > 0)
6336- (void)mouseEntered: (NSEvent *)theEvent 6338- (void)mouseEntered: (NSEvent *)theEvent
6337{ 6339{
6338 NSTRACE (mouseEntered); 6340 NSTRACE (mouseEntered);
6339 last_mouse_movement_time = EV_TIMESTAMP (theEvent); 6341 if (emacsframe)
6342 FRAME_DISPLAY_INFO (emacsframe)->last_mouse_movement_time
6343 = EV_TIMESTAMP (theEvent);
6340} 6344}
6341 6345
6342 6346
@@ -6349,7 +6353,8 @@ if (cols > 0 && rows > 0)
6349 if (!hlinfo) 6353 if (!hlinfo)
6350 return; 6354 return;
6351 6355
6352 last_mouse_movement_time = EV_TIMESTAMP (theEvent); 6356 FRAME_DISPLAY_INFO (emacsframe)->last_mouse_movement_time
6357 = EV_TIMESTAMP (theEvent);
6353 6358
6354 if (emacsframe == hlinfo->mouse_face_mouse_frame) 6359 if (emacsframe == hlinfo->mouse_face_mouse_frame)
6355 { 6360 {
diff --git a/src/w32term.c b/src/w32term.c
index 805ee59ea4f..3377a8911e2 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -171,31 +171,6 @@ int last_scroll_bar_drag_pos;
171/* Keyboard code page - may be changed by language-change events. */ 171/* Keyboard code page - may be changed by language-change events. */
172int w32_keyboard_codepage; 172int w32_keyboard_codepage;
173 173
174/* Mouse movement. */
175
176/* Where the mouse was last time we reported a mouse event. */
177static RECT last_mouse_glyph;
178static struct frame *last_mouse_glyph_frame;
179
180/* The scroll bar in which the last motion event occurred.
181
182 If the last motion event occurred in a scroll bar, we set this
183 so w32_mouse_position can know whether to report a scroll bar motion or
184 an ordinary motion.
185
186 If the last motion event didn't occur in a scroll bar, we set this
187 to Qnil, to tell w32_mouse_position to return an ordinary motion event. */
188static Lisp_Object last_mouse_scroll_bar;
189static int last_mouse_scroll_bar_pos;
190
191/* This is a hack. We would really prefer that w32_mouse_position would
192 return the time associated with the position it returns, but there
193 doesn't seem to be any way to wrest the time-stamp from the server
194 along with the position query. So, we just keep track of the time
195 of the last movement we received, and return that in hopes that
196 it's somewhat accurate. */
197static Time last_mouse_movement_time;
198
199/* Incremented by w32_read_socket whenever it really tries to read 174/* Incremented by w32_read_socket whenever it really tries to read
200 events. */ 175 events. */
201static int volatile input_signal_count; 176static int volatile input_signal_count;
@@ -3310,12 +3285,13 @@ note_mouse_movement (struct frame *frame, MSG *msg)
3310 struct w32_display_info *dpyinfo; 3285 struct w32_display_info *dpyinfo;
3311 int mouse_x = LOWORD (msg->lParam); 3286 int mouse_x = LOWORD (msg->lParam);
3312 int mouse_y = HIWORD (msg->lParam); 3287 int mouse_y = HIWORD (msg->lParam);
3288 RECT *r;
3313 3289
3314 if (!FRAME_X_OUTPUT (frame)) 3290 if (!FRAME_X_OUTPUT (frame))
3315 return 0; 3291 return 0;
3316 3292
3317 dpyinfo = FRAME_DISPLAY_INFO (frame); 3293 dpyinfo = FRAME_DISPLAY_INFO (frame);
3318 last_mouse_movement_time = msg->time; 3294 dpyinfo->last_mouse_movement_time = msg->time;
3319 dpyinfo->last_mouse_motion_frame = frame; 3295 dpyinfo->last_mouse_motion_frame = frame;
3320 dpyinfo->last_mouse_motion_x = mouse_x; 3296 dpyinfo->last_mouse_motion_x = mouse_x;
3321 dpyinfo->last_mouse_motion_y = mouse_y; 3297 dpyinfo->last_mouse_motion_y = mouse_y;
@@ -3323,28 +3299,27 @@ note_mouse_movement (struct frame *frame, MSG *msg)
3323 if (msg->hwnd != FRAME_W32_WINDOW (frame)) 3299 if (msg->hwnd != FRAME_W32_WINDOW (frame))
3324 { 3300 {
3325 frame->mouse_moved = 1; 3301 frame->mouse_moved = 1;
3326 last_mouse_scroll_bar = Qnil; 3302 dpyinfo->last_mouse_scroll_bar = NULL;
3327 note_mouse_highlight (frame, -1, -1); 3303 note_mouse_highlight (frame, -1, -1);
3328 last_mouse_glyph_frame = 0; 3304 dpyinfo->last_mouse_glyph_frame = NULL;
3329 return 1; 3305 return 1;
3330 } 3306 }
3331 3307
3332 /* Has the mouse moved off the glyph it was on at the last sighting? */ 3308 /* Has the mouse moved off the glyph it was on at the last sighting? */
3333 if (frame != last_mouse_glyph_frame 3309 r = &dpyinfo->last_mouse_glyph;
3334 || mouse_x < last_mouse_glyph.left 3310 if (frame != dpyinfo->last_mouse_glyph_frame
3335 || mouse_x >= last_mouse_glyph.right 3311 || mouse_x < r->left || mouse_x >= r->right
3336 || mouse_y < last_mouse_glyph.top 3312 || mouse_y < r->top || mouse_y >= r->bottom)
3337 || mouse_y >= last_mouse_glyph.bottom)
3338 { 3313 {
3339 frame->mouse_moved = 1; 3314 frame->mouse_moved = 1;
3340 last_mouse_scroll_bar = Qnil; 3315 dpyinfo->last_mouse_scroll_bar = NULL;
3341 note_mouse_highlight (frame, mouse_x, mouse_y); 3316 note_mouse_highlight (frame, mouse_x, mouse_y);
3342 /* Remember the mouse position here, as w32_mouse_position only 3317 /* Remember the mouse position here, as w32_mouse_position only
3343 gets called when mouse tracking is enabled but we also need 3318 gets called when mouse tracking is enabled but we also need
3344 to keep track of the mouse for help_echo and highlighting at 3319 to keep track of the mouse for help_echo and highlighting at
3345 other times. */ 3320 other times. */
3346 remember_mouse_glyph (frame, mouse_x, mouse_y, &last_mouse_glyph); 3321 remember_mouse_glyph (frame, mouse_x, mouse_y, r);
3347 last_mouse_glyph_frame = frame; 3322 dpyinfo->last_mouse_glyph_frame = frame;
3348 return 1; 3323 return 1;
3349 } 3324 }
3350 3325
@@ -3398,7 +3373,7 @@ w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
3398 3373
3399 block_input (); 3374 block_input ();
3400 3375
3401 if (! NILP (last_mouse_scroll_bar) && insist == 0) 3376 if (dpyinfo->last_mouse_scroll_bar && insist == 0)
3402 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time); 3377 x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
3403 else 3378 else
3404 { 3379 {
@@ -3410,7 +3385,7 @@ w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
3410 FOR_EACH_FRAME (tail, frame) 3385 FOR_EACH_FRAME (tail, frame)
3411 XFRAME (frame)->mouse_moved = 0; 3386 XFRAME (frame)->mouse_moved = 0;
3412 3387
3413 last_mouse_scroll_bar = Qnil; 3388 dpyinfo->last_mouse_scroll_bar = NULL;
3414 3389
3415 GetCursorPos (&pt); 3390 GetCursorPos (&pt);
3416 3391
@@ -3448,16 +3423,17 @@ w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
3448 on it, i.e. into the same rectangles that matrices on 3423 on it, i.e. into the same rectangles that matrices on
3449 the frame are divided into. */ 3424 the frame are divided into. */
3450 3425
3426 dpyinfo = FRAME_DISPLAY_INFO (f1);
3451 ScreenToClient (FRAME_W32_WINDOW (f1), &pt); 3427 ScreenToClient (FRAME_W32_WINDOW (f1), &pt);
3452 remember_mouse_glyph (f1, pt.x, pt.y, &last_mouse_glyph); 3428 remember_mouse_glyph (f1, pt.x, pt.y, &dpyinfo->last_mouse_glyph);
3453 last_mouse_glyph_frame = f1; 3429 dpyinfo->last_mouse_glyph_frame = f1;
3454 3430
3455 *bar_window = Qnil; 3431 *bar_window = Qnil;
3456 *part = 0; 3432 *part = 0;
3457 *fp = f1; 3433 *fp = f1;
3458 XSETINT (*x, pt.x); 3434 XSETINT (*x, pt.x);
3459 XSETINT (*y, pt.y); 3435 XSETINT (*y, pt.y);
3460 *time = last_mouse_movement_time; 3436 *time = dpyinfo->last_mouse_movement_time;
3461 } 3437 }
3462 } 3438 }
3463 } 3439 }
@@ -4005,6 +3981,7 @@ w32_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
4005 3981
4006 { 3982 {
4007 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)); 3983 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
3984 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
4008 int y; 3985 int y;
4009 int dragging = !NILP (bar->dragging); 3986 int dragging = !NILP (bar->dragging);
4010 SCROLLINFO si; 3987 SCROLLINFO si;
@@ -4016,9 +3993,7 @@ w32_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg,
4016 y = si.nPos; 3993 y = si.nPos;
4017 3994
4018 bar->dragging = Qnil; 3995 bar->dragging = Qnil;
4019 3996 FRAME_DISPLAY_INFO (f)->last_mouse_scroll_bar_pos = msg->msg.wParam;
4020
4021 last_mouse_scroll_bar_pos = msg->msg.wParam;
4022 3997
4023 switch (LOWORD (msg->msg.wParam)) 3998 switch (LOWORD (msg->msg.wParam))
4024 { 3999 {
@@ -4101,7 +4076,8 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
4101 Lisp_Object *x, Lisp_Object *y, 4076 Lisp_Object *x, Lisp_Object *y,
4102 unsigned long *time) 4077 unsigned long *time)
4103{ 4078{
4104 struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar); 4079 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
4080 struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
4105 Window w = SCROLL_BAR_W32_WINDOW (bar); 4081 Window w = SCROLL_BAR_W32_WINDOW (bar);
4106 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); 4082 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
4107 int pos; 4083 int pos;
@@ -4120,13 +4096,13 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
4120 pos = si.nPos; 4096 pos = si.nPos;
4121 top_range = si.nMax - si.nPage + 1; 4097 top_range = si.nMax - si.nPage + 1;
4122 4098
4123 switch (LOWORD (last_mouse_scroll_bar_pos)) 4099 switch (LOWORD (dpyinfo->last_mouse_scroll_bar_pos))
4124 { 4100 {
4125 case SB_THUMBPOSITION: 4101 case SB_THUMBPOSITION:
4126 case SB_THUMBTRACK: 4102 case SB_THUMBTRACK:
4127 *part = scroll_bar_handle; 4103 *part = scroll_bar_handle;
4128 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)) <= 0xffff) 4104 if (VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height)) <= 0xffff)
4129 pos = HIWORD (last_mouse_scroll_bar_pos); 4105 pos = HIWORD (dpyinfo->last_mouse_scroll_bar_pos);
4130 break; 4106 break;
4131 case SB_LINEDOWN: 4107 case SB_LINEDOWN:
4132 *part = scroll_bar_handle; 4108 *part = scroll_bar_handle;
@@ -4141,9 +4117,9 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
4141 XSETINT (*y, top_range); 4117 XSETINT (*y, top_range);
4142 4118
4143 f->mouse_moved = 0; 4119 f->mouse_moved = 0;
4144 last_mouse_scroll_bar = Qnil; 4120 dpyinfo->last_mouse_scroll_bar = NULL;
4145 4121
4146 *time = last_mouse_movement_time; 4122 *time = dpyinfo->last_mouse_movement_time;
4147 4123
4148 unblock_input (); 4124 unblock_input ();
4149} 4125}
@@ -6553,9 +6529,6 @@ syms_of_w32term (void)
6553 staticpro (&w32_display_name_list); 6529 staticpro (&w32_display_name_list);
6554 w32_display_name_list = Qnil; 6530 w32_display_name_list = Qnil;
6555 6531
6556 staticpro (&last_mouse_scroll_bar);
6557 last_mouse_scroll_bar = Qnil;
6558
6559 DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms"); 6532 DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
6560 6533
6561 DEFSYM (Qadded, "added"); 6534 DEFSYM (Qadded, "added");
diff --git a/src/w32term.h b/src/w32term.h
index ef7f0842680..21b9b6894a7 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -189,10 +189,27 @@ struct w32_display_info
189 /* The frame where the mouse was last time we reported a mouse motion. */ 189 /* The frame where the mouse was last time we reported a mouse motion. */
190 struct frame *last_mouse_motion_frame; 190 struct frame *last_mouse_motion_frame;
191 191
192 /* The frame where the mouse was last time we reported a mouse position. */
193 struct frame *last_mouse_glyph_frame;
194
192 /* Position where the mouse was last time we reported a motion. 195 /* Position where the mouse was last time we reported a motion.
193 This is a position on last_mouse_motion_frame. */ 196 This is a position on last_mouse_motion_frame. */
194 int last_mouse_motion_x; 197 int last_mouse_motion_x;
195 int last_mouse_motion_y; 198 int last_mouse_motion_y;
199
200 /* Where the mouse was last time we reported a mouse position.
201 This is a rectangle on last_mouse_glyph_frame. */
202 RECT last_mouse_glyph;
203
204 /* The scroll bar in which the last motion event occurred. */
205 struct scroll_bar *last_mouse_scroll_bar;
206
207 /* Mouse position on the scroll bar above.
208 FIXME: shouldn't it be a member of struct scroll_bar? */
209 int last_mouse_scroll_bar_pos;
210
211 /* Time of last mouse movement. */
212 Time last_mouse_movement_time;
196}; 213};
197 214
198/* This is a chain of structures for all the displays currently in use. */ 215/* This is a chain of structures for all the displays currently in use. */
diff --git a/src/xterm.c b/src/xterm.c
index f52466f52d1..963cd4d8896 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -172,52 +172,6 @@ static bool toolkit_scroll_bar_interaction;
172 172
173static Time ignore_next_mouse_click_timeout; 173static Time ignore_next_mouse_click_timeout;
174 174
175/* Mouse movement.
176
177 Formerly, we used PointerMotionHintMask (in standard_event_mask)
178 so that we would have to call XQueryPointer after each MotionNotify
179 event to ask for another such event. However, this made mouse tracking
180 slow, and there was a bug that made it eventually stop.
181
182 Simply asking for MotionNotify all the time seems to work better.
183
184 In order to avoid asking for motion events and then throwing most
185 of them away or busy-polling the server for mouse positions, we ask
186 the server for pointer motion hints. This means that we get only
187 one event per group of mouse movements. "Groups" are delimited by
188 other kinds of events (focus changes and button clicks, for
189 example), or by XQueryPointer calls; when one of these happens, we
190 get another MotionNotify event the next time the mouse moves. This
191 is at least as efficient as getting motion events when mouse
192 tracking is on, and I suspect only negligibly worse when tracking
193 is off. */
194
195/* Where the mouse was last time we reported a mouse event. */
196
197static XRectangle last_mouse_glyph;
198static struct frame *last_mouse_glyph_frame;
199
200/* The scroll bar in which the last X motion event occurred.
201
202 If the last X motion event occurred in a scroll bar, we set this so
203 XTmouse_position can know whether to report a scroll bar motion or
204 an ordinary motion.
205
206 If the last X motion event didn't occur in a scroll bar, we set
207 this to Qnil, to tell XTmouse_position to return an ordinary motion
208 event. */
209
210static Lisp_Object last_mouse_scroll_bar;
211
212/* This is a hack. We would really prefer that XTmouse_position would
213 return the time associated with the position it returns, but there
214 doesn't seem to be any way to wrest the time-stamp from the server
215 along with the position query. So, we just keep track of the time
216 of the last movement we received, and return that in hopes that
217 it's somewhat accurate. */
218
219static Time last_mouse_movement_time;
220
221/* Incremented by XTread_socket whenever it really tries to read 175/* Incremented by XTread_socket whenever it really tries to read
222 events. */ 176 events. */
223 177
@@ -3820,9 +3774,25 @@ x_get_keysym_name (int keysym)
3820 return value; 3774 return value;
3821} 3775}
3822 3776
3777/* Mouse clicks and mouse movement. Rah.
3823 3778
3824 3779 Formerly, we used PointerMotionHintMask (in standard_event_mask)
3825/* Mouse clicks and mouse movement. Rah. */ 3780 so that we would have to call XQueryPointer after each MotionNotify
3781 event to ask for another such event. However, this made mouse tracking
3782 slow, and there was a bug that made it eventually stop.
3783
3784 Simply asking for MotionNotify all the time seems to work better.
3785
3786 In order to avoid asking for motion events and then throwing most
3787 of them away or busy-polling the server for mouse positions, we ask
3788 the server for pointer motion hints. This means that we get only
3789 one event per group of mouse movements. "Groups" are delimited by
3790 other kinds of events (focus changes and button clicks, for
3791 example), or by XQueryPointer calls; when one of these happens, we
3792 get another MotionNotify event the next time the mouse moves. This
3793 is at least as efficient as getting motion events when mouse
3794 tracking is on, and I suspect only negligibly worse when tracking
3795 is off. */
3826 3796
3827/* Prepare a mouse-event in *RESULT for placement in the input queue. 3797/* Prepare a mouse-event in *RESULT for placement in the input queue.
3828 3798
@@ -3863,13 +3833,14 @@ construct_mouse_click (struct input_event *result,
3863static int 3833static int
3864note_mouse_movement (struct frame *frame, const XMotionEvent *event) 3834note_mouse_movement (struct frame *frame, const XMotionEvent *event)
3865{ 3835{
3836 XRectangle *r;
3866 struct x_display_info *dpyinfo; 3837 struct x_display_info *dpyinfo;
3867 3838
3868 if (!FRAME_X_OUTPUT (frame)) 3839 if (!FRAME_X_OUTPUT (frame))
3869 return 0; 3840 return 0;
3870 3841
3871 dpyinfo = FRAME_DISPLAY_INFO (frame); 3842 dpyinfo = FRAME_DISPLAY_INFO (frame);
3872 last_mouse_movement_time = event->time; 3843 dpyinfo->last_mouse_movement_time = event->time;
3873 dpyinfo->last_mouse_motion_frame = frame; 3844 dpyinfo->last_mouse_motion_frame = frame;
3874 dpyinfo->last_mouse_motion_x = event->x; 3845 dpyinfo->last_mouse_motion_x = event->x;
3875 dpyinfo->last_mouse_motion_y = event->y; 3846 dpyinfo->last_mouse_motion_y = event->y;
@@ -3877,26 +3848,25 @@ note_mouse_movement (struct frame *frame, const XMotionEvent *event)
3877 if (event->window != FRAME_X_WINDOW (frame)) 3848 if (event->window != FRAME_X_WINDOW (frame))
3878 { 3849 {
3879 frame->mouse_moved = 1; 3850 frame->mouse_moved = 1;
3880 last_mouse_scroll_bar = Qnil; 3851 dpyinfo->last_mouse_scroll_bar = NULL;
3881 note_mouse_highlight (frame, -1, -1); 3852 note_mouse_highlight (frame, -1, -1);
3882 last_mouse_glyph_frame = 0; 3853 dpyinfo->last_mouse_glyph_frame = NULL;
3883 return 1; 3854 return 1;
3884 } 3855 }
3885 3856
3886 3857
3887 /* Has the mouse moved off the glyph it was on at the last sighting? */ 3858 /* Has the mouse moved off the glyph it was on at the last sighting? */
3888 if (frame != last_mouse_glyph_frame 3859 r = &dpyinfo->last_mouse_glyph;
3889 || event->x < last_mouse_glyph.x 3860 if (frame != dpyinfo->last_mouse_glyph_frame
3890 || event->x >= last_mouse_glyph.x + last_mouse_glyph.width 3861 || event->x < r->x || event->x >= r->x + r->width
3891 || event->y < last_mouse_glyph.y 3862 || event->y < r->y || event->y >= r->y + r->height)
3892 || event->y >= last_mouse_glyph.y + last_mouse_glyph.height)
3893 { 3863 {
3894 frame->mouse_moved = 1; 3864 frame->mouse_moved = 1;
3895 last_mouse_scroll_bar = Qnil; 3865 dpyinfo->last_mouse_scroll_bar = NULL;
3896 note_mouse_highlight (frame, event->x, event->y); 3866 note_mouse_highlight (frame, event->x, event->y);
3897 /* Remember which glyph we're now on. */ 3867 /* Remember which glyph we're now on. */
3898 remember_mouse_glyph (frame, event->x, event->y, &last_mouse_glyph); 3868 remember_mouse_glyph (frame, event->x, event->y, r);
3899 last_mouse_glyph_frame = frame; 3869 dpyinfo->last_mouse_glyph_frame = frame;
3900 return 1; 3870 return 1;
3901 } 3871 }
3902 3872
@@ -3933,7 +3903,7 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
3933 3903
3934 block_input (); 3904 block_input ();
3935 3905
3936 if (! NILP (last_mouse_scroll_bar) && insist == 0) 3906 if (dpyinfo->last_mouse_scroll_bar && insist == 0)
3937 x_scroll_bar_report_motion (fp, bar_window, part, x, y, timestamp); 3907 x_scroll_bar_report_motion (fp, bar_window, part, x, y, timestamp);
3938 else 3908 else
3939 { 3909 {
@@ -3951,7 +3921,7 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
3951 && FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp)) 3921 && FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp))
3952 XFRAME (frame)->mouse_moved = 0; 3922 XFRAME (frame)->mouse_moved = 0;
3953 3923
3954 last_mouse_scroll_bar = Qnil; 3924 dpyinfo->last_mouse_scroll_bar = NULL;
3955 3925
3956 /* Figure out which root window we're on. */ 3926 /* Figure out which root window we're on. */
3957 XQueryPointer (FRAME_X_DISPLAY (*fp), 3927 XQueryPointer (FRAME_X_DISPLAY (*fp),
@@ -4101,15 +4071,17 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
4101 on it, i.e. into the same rectangles that matrices on 4071 on it, i.e. into the same rectangles that matrices on
4102 the frame are divided into. */ 4072 the frame are divided into. */
4103 4073
4104 remember_mouse_glyph (f1, win_x, win_y, &last_mouse_glyph); 4074 /* FIXME: what if F1 is not an X frame? */
4105 last_mouse_glyph_frame = f1; 4075 dpyinfo = FRAME_DISPLAY_INFO (f1);
4076 remember_mouse_glyph (f1, win_x, win_y, &dpyinfo->last_mouse_glyph);
4077 dpyinfo->last_mouse_glyph_frame = f1;
4106 4078
4107 *bar_window = Qnil; 4079 *bar_window = Qnil;
4108 *part = 0; 4080 *part = 0;
4109 *fp = f1; 4081 *fp = f1;
4110 XSETINT (*x, win_x); 4082 XSETINT (*x, win_x);
4111 XSETINT (*y, win_y); 4083 XSETINT (*y, win_y);
4112 *timestamp = last_mouse_movement_time; 4084 *timestamp = dpyinfo->last_mouse_movement_time;
4113 } 4085 }
4114 } 4086 }
4115 } 4087 }
@@ -5589,11 +5561,11 @@ x_scroll_bar_note_movement (struct scroll_bar *bar,
5589 const XMotionEvent *event) 5561 const XMotionEvent *event)
5590{ 5562{
5591 struct frame *f = XFRAME (XWINDOW (bar->window)->frame); 5563 struct frame *f = XFRAME (XWINDOW (bar->window)->frame);
5564 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
5592 5565
5593 last_mouse_movement_time = event->time; 5566 dpyinfo->last_mouse_movement_time = event->time;
5594 5567 dpyinfo->last_mouse_scroll_bar = bar;
5595 f->mouse_moved = 1; 5568 f->mouse_moved = 1;
5596 XSETVECTOR (last_mouse_scroll_bar, bar);
5597 5569
5598 /* If we're dragging the bar, display it. */ 5570 /* If we're dragging the bar, display it. */
5599 if (bar->dragging != -1) 5571 if (bar->dragging != -1)
@@ -5620,7 +5592,8 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
5620 enum scroll_bar_part *part, Lisp_Object *x, 5592 enum scroll_bar_part *part, Lisp_Object *x,
5621 Lisp_Object *y, Time *timestamp) 5593 Lisp_Object *y, Time *timestamp)
5622{ 5594{
5623 struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar); 5595 struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
5596 struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar;
5624 Window w = bar->x_window; 5597 Window w = bar->x_window;
5625 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window))); 5598 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
5626 int win_x, win_y; 5599 int win_x, win_y;
@@ -5632,22 +5605,19 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
5632 5605
5633 /* Get the mouse's position relative to the scroll bar window, and 5606 /* Get the mouse's position relative to the scroll bar window, and
5634 report that. */ 5607 report that. */
5635 if (! XQueryPointer (FRAME_X_DISPLAY (f), w, 5608 if (XQueryPointer (FRAME_X_DISPLAY (f), w,
5636 5609
5637 /* Root, child, root x and root y. */ 5610 /* Root, child, root x and root y. */
5638 &dummy_window, &dummy_window, 5611 &dummy_window, &dummy_window,
5639 &dummy_coord, &dummy_coord, 5612 &dummy_coord, &dummy_coord,
5640 5613
5641 /* Position relative to scroll bar. */ 5614 /* Position relative to scroll bar. */
5642 &win_x, &win_y, 5615 &win_x, &win_y,
5643 5616
5644 /* Mouse buttons and modifier keys. */ 5617 /* Mouse buttons and modifier keys. */
5645 &dummy_mask)) 5618 &dummy_mask))
5646 ;
5647 else
5648 { 5619 {
5649 int top_range 5620 int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
5650 = VERTICAL_SCROLL_BAR_TOP_RANGE (f, bar->height);
5651 5621
5652 win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER; 5622 win_y -= VERTICAL_SCROLL_BAR_TOP_BORDER;
5653 5623
@@ -5675,11 +5645,10 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
5675 XSETINT (*y, top_range); 5645 XSETINT (*y, top_range);
5676 5646
5677 f->mouse_moved = 0; 5647 f->mouse_moved = 0;
5678 last_mouse_scroll_bar = Qnil; 5648 dpyinfo->last_mouse_scroll_bar = NULL;
5649 *timestamp = dpyinfo->last_mouse_movement_time;
5679 } 5650 }
5680 5651
5681 *timestamp = last_mouse_movement_time;
5682
5683 unblock_input (); 5652 unblock_input ();
5684} 5653}
5685 5654
@@ -6644,8 +6613,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
6644#ifdef USE_GTK 6613#ifdef USE_GTK
6645 /* We may get an EnterNotify on the buttons in the toolbar. In that 6614 /* We may get an EnterNotify on the buttons in the toolbar. In that
6646 case we moved out of any highlighted area and need to note this. */ 6615 case we moved out of any highlighted area and need to note this. */
6647 if (!f && last_mouse_glyph_frame) 6616 if (!f && dpyinfo->last_mouse_glyph_frame)
6648 note_mouse_movement (last_mouse_glyph_frame, &event->xmotion); 6617 note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &event->xmotion);
6649#endif 6618#endif
6650 goto OTHER; 6619 goto OTHER;
6651 6620
@@ -6677,8 +6646,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
6677 } 6646 }
6678#ifdef USE_GTK 6647#ifdef USE_GTK
6679 /* See comment in EnterNotify above */ 6648 /* See comment in EnterNotify above */
6680 else if (last_mouse_glyph_frame) 6649 else if (dpyinfo->last_mouse_glyph_frame)
6681 note_mouse_movement (last_mouse_glyph_frame, &event->xmotion); 6650 note_mouse_movement (dpyinfo->last_mouse_glyph_frame, &event->xmotion);
6682#endif 6651#endif
6683 goto OTHER; 6652 goto OTHER;
6684 6653
@@ -6827,7 +6796,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
6827 bool tool_bar_p = 0; 6796 bool tool_bar_p = 0;
6828 6797
6829 memset (&compose_status, 0, sizeof (compose_status)); 6798 memset (&compose_status, 0, sizeof (compose_status));
6830 last_mouse_glyph_frame = 0; 6799 dpyinfo->last_mouse_glyph_frame = NULL;
6831 dpyinfo->last_user_time = event->xbutton.time; 6800 dpyinfo->last_user_time = event->xbutton.time;
6832 6801
6833 f = (x_mouse_grabbed (dpyinfo) ? dpyinfo->last_mouse_frame 6802 f = (x_mouse_grabbed (dpyinfo) ? dpyinfo->last_mouse_frame
@@ -10629,9 +10598,6 @@ syms_of_xterm (void)
10629 staticpro (&x_display_name_list); 10598 staticpro (&x_display_name_list);
10630 x_display_name_list = Qnil; 10599 x_display_name_list = Qnil;
10631 10600
10632 staticpro (&last_mouse_scroll_bar);
10633 last_mouse_scroll_bar = Qnil;
10634
10635 DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms"); 10601 DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
10636 DEFSYM (Qlatin_1, "latin-1"); 10602 DEFSYM (Qlatin_1, "latin-1");
10637 10603
diff --git a/src/xterm.h b/src/xterm.h
index 9f01a840e53..36aa8e52b1c 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -305,12 +305,18 @@ struct x_display_info
305 /* The frame waiting to be auto-raised in XTread_socket. */ 305 /* The frame waiting to be auto-raised in XTread_socket. */
306 struct frame *x_pending_autoraise_frame; 306 struct frame *x_pending_autoraise_frame;
307 307
308 /* The frame where the mouse was last time we reported a mouse event. */ 308 /* The frame where the mouse was last time we reported a ButtonPress event. */
309 struct frame *last_mouse_frame; 309 struct frame *last_mouse_frame;
310 310
311 /* The frame where the mouse was last time we reported a mouse position. */
312 struct frame *last_mouse_glyph_frame;
313
311 /* The frame where the mouse was last time we reported a mouse motion. */ 314 /* The frame where the mouse was last time we reported a mouse motion. */
312 struct frame *last_mouse_motion_frame; 315 struct frame *last_mouse_motion_frame;
313 316
317 /* The scroll bar in which the last X motion event occurred. */
318 struct scroll_bar *last_mouse_scroll_bar;
319
314 /* Time of last user interaction as returned in X events on this display. */ 320 /* Time of last user interaction as returned in X events on this display. */
315 Time last_user_time; 321 Time last_user_time;
316 322
@@ -319,6 +325,18 @@ struct x_display_info
319 int last_mouse_motion_x; 325 int last_mouse_motion_x;
320 int last_mouse_motion_y; 326 int last_mouse_motion_y;
321 327
328 /* Where the mouse was last time we reported a mouse position.
329 This is a rectangle on last_mouse_glyph_frame. */
330 XRectangle last_mouse_glyph;
331
332 /* Time of last mouse movement on this display. This is a hack because
333 we would really prefer that XTmouse_position would return the time
334 associated with the position it returns, but there doesn't seem to be
335 any way to wrest the time-stamp from the server along with the position
336 query. So, we just keep track of the time of the last movement we
337 received, and return that in hopes that it's somewhat accurate. */
338 Time last_mouse_movement_time;
339
322 /* The gray pixmap. */ 340 /* The gray pixmap. */
323 Pixmap gray; 341 Pixmap gray;
324 342