diff options
| author | Dmitry Antipov | 2013-09-19 11:48:53 +0400 |
|---|---|---|
| committer | Dmitry Antipov | 2013-09-19 11:48:53 +0400 |
| commit | ced135ebdbfb0eea719ce165a454e7ff0b681e88 (patch) | |
| tree | 17311f84267e23afbd4d1131ea2fe1fa14aa6f55 /src/xterm.c | |
| parent | f75447737926fd8c898b9e0b77f581f4993a52f1 (diff) | |
| download | emacs-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.c | 148 |
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 | ||
| 173 | static Time ignore_next_mouse_click_timeout; | 173 | static 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 | |||
| 197 | static XRectangle last_mouse_glyph; | ||
| 198 | static 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 | |||
| 210 | static 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 | |||
| 219 | static 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, | |||
| 3863 | static int | 3833 | static int |
| 3864 | note_mouse_movement (struct frame *frame, const XMotionEvent *event) | 3834 | note_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 | ||