-#if FL_REVISION < 89
- case FL_MOUSE:
-#else
- case FL_DRAG:
-#endif
- if (!ev || ! area->scrollbar) break;
- if (ev->xmotion.x != x_old ||
- ev->xmotion.y != y_old ||
- fl_get_scrollbar_value(area->scrollbar) != scrollbar_value_old
- ) {
- lyxerr[Debug::WORKAREA] << "Workarea event: MOUSE" << endl;
- area->workAreaMotionNotify(ev->xmotion.x - ob->x,
- ev->xmotion.y - ob->y,
- x_motion_state(ev->xbutton.state));
+
+ case FL_DRAG: {
+ lyxerr[Debug::WORKAREA] << "Workarea event: DRAG 0" << endl;
+
+ if (!ev || !area->scrollbar)
+ break;
+
+ int const drag_x = ev->xmotion.x;
+ int const drag_y = ev->xmotion.y;
+ int const area_y = ob->y;
+ int const area_h = ob->h;
+
+ // Check if the mouse is above or below the workarea
+ if (drag_y <= area_y || drag_y >= area_y + area_h) {
+ // The mouse button is depressed and we are outside the
+ // workarea. That means we are simultaneously selecting
+ // text and scrolling the view.
+ // Use a Timeout to react to a drag events only every
+ // 200ms. All intervening events are discarded,
+ // allowing the user to control position easily.
+ static int const discard_interval = 200;
+ static Timeout timeout(discard_interval);
+
+ if (timeout.running())
+ break;
+ // The timeout is not running, so process the
+ // event, first starting the timeout to discard future
+ // events.
+ timeout.start();
+ }
+
+ static int x_old = -1;
+ static int y_old = -1;
+ static double scrollbar_value_old = -1.0;
+
+ double const scrollbar_value =
+ fl_get_scrollbar_value(area->scrollbar);
+
+ if (drag_x != x_old || drag_y != y_old ||
+ scrollbar_value != scrollbar_value_old) {
+ x_old = drag_x;
+ y_old = drag_y;
+ scrollbar_value_old = scrollbar_value;
+
+ lyxerr[Debug::WORKAREA] << "Workarea event: DRAG"
+ << endl;
+
+ // It transpires that ev->xbutton.button == 0 when
+ // the mouse is dragged, so it cannot be used to
+ // initialise x_button_state and hence FuncRequest.
+
+ // The 'key' that is passed into the function does
+ // contain the necessary info, however.
+
+ // It is for this reason that x_button_state has
+ // been modified to work with key
+ // rather than ev->xbutton.button.
+
+ // Angus 15 Oct 2002.
+ FuncRequest cmd(LFUN_MOUSE_MOTION,
+ ev->xbutton.x - ob->x,
+ ev->xbutton.y - ob->y,
+ x_button_state(key));
+ area->dispatch(cmd);