From ced135ebdbfb0eea719ce165a454e7ff0b681e88 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Thu, 19 Sep 2013 11:48:53 +0400 Subject: [PATCH] * 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. --- src/ChangeLog | 27 +++++++++ src/nsterm.h | 13 +++++ src/nsterm.m | 49 +++++++++-------- src/w32term.c | 77 +++++++++----------------- src/w32term.h | 17 ++++++ src/xterm.c | 148 +++++++++++++++++++------------------------------- src/xterm.h | 20 ++++++- 7 files changed, 185 insertions(+), 166 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 2a931693f6..d900818231 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,30 @@ +2013-09-19 Dmitry Antipov + + * 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 Do not use external array to process X scroll bar messages. diff --git a/src/nsterm.h b/src/nsterm.h index 7a626c75fe..9f7767b312 100644 --- a/src/nsterm.h +++ b/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. */ diff --git a/src/nsterm.m b/src/nsterm.m index dc27fd09e3..5c9800f541 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -191,9 +191,6 @@ Lisp_Object ns_display_name_list; 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 @@ note_mouse_movement (struct frame *frame, CGFloat x, CGFloat y) 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 @@ ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, 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 @@ ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, && 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 @@ ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, 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 @@ ns_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, 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 @@ not_in_argv (NSString *arg) // 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 @@ if (cols > 0 && rows > 0) - (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 @@ if (cols > 0 && rows > 0) 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) { diff --git a/src/w32term.c b/src/w32term.c index 805ee59ea4..3377a8911e 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -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"); diff --git a/src/w32term.h b/src/w32term.h index ef7f084268..21b9b6894a 100644 --- a/src/w32term.h +++ b/src/w32term.h @@ -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. */ diff --git a/src/xterm.c b/src/xterm.c index f52466f52d..963cd4d889 100644 --- a/src/xterm.c +++ b/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"); diff --git a/src/xterm.h b/src/xterm.h index 9f01a840e5..36aa8e52b1 100644 --- a/src/xterm.h +++ b/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; -- 2.20.1