aboutsummaryrefslogtreecommitdiffstats
path: root/src/xterm.c
diff options
context:
space:
mode:
authorDmitry Antipov2013-09-19 11:48:53 +0400
committerDmitry Antipov2013-09-19 11:48:53 +0400
commitced135ebdbfb0eea719ce165a454e7ff0b681e88 (patch)
tree17311f84267e23afbd4d1131ea2fe1fa14aa6f55 /src/xterm.c
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.
Diffstat (limited to 'src/xterm.c')
-rw-r--r--src/xterm.c148
1 files changed, 57 insertions, 91 deletions
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