Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4094664

Allow DBL-clicks to be detected within a "tolerance" between two successive pts.

XMLWordPrintable

    • x86
    • windows_95

      orig synopsis: "Mouse clicked events [espec'lly DBL-clicks] aren't properly handled in Win32 (pen input)"

      Name: joT67522 Date: 11/21/97


      Bug :
      We are using a pen input device in place of a mouse. This means we have less than perfect
      control over where we are when we double or single click. This means that we often miss double click
      (and single click?) events. Looking at the jdk1.1.4 source code [src\win32\sun\windows\awt_Component.cpp],
      we believe we have found the source of this totally unsatisfactory behaviour.

      First here is the behaviour we would like to see :

      (1) When java receives the mouse down message, it tracks the time and
      the X, and Y position. (line 952, lastClickTime, lastClickX, and lastClickY)
      (2) When java receives a mouse moved message, it compares this to the
      X and Y position from the mouse down, and, should it be outside of a SYSTEM preference,
      a drag state varaible is set. (similar to line 953 and 954).
      (3) When java receives a mouse up event, it determines if there was no
      mouse dragged. If not, it fires a mouseClicked event in addition to the mouseReleased.
      (line 973...)

      The current implementation differs in step (2)
      (2) Mouse moved events are naively compared for equality. You must be in
      EXACTLY the same spot to avoid setting the mouse dragged state variable! (line 1001), and
      thereby, in step (3) failing to trigger the mouseClicked event. This is totally wrong! There is
      a reason our operating system lets us specify input device sensitivity, Java should not ignore this.



      FILE : "src\win32\sun\windows\awt_Component.cpp"

      [936] // Double-click variables.
      static ULONG multiClickTime = ::GetDoubleClickTime();
      static int multiClickMaxX = ::GetSystemMetrics(SM_CXDOUBLECLK);
      static int multiClickMaxY = ::GetSystemMetrics(SM_CYDOUBLECLK);
      [940] static AwtComponent* lastClickWnd = NULL;
      static ULONG lastTime = 0;
      static int lastClickX = 0;
      static int lastClickY = 0;
      static int clickCount = 0;

      MsgRouting AwtComponent::WmMouseDown(UINT flags, int x, int y, int button)
      {
      __int64 tm = nowMillis();

      [950] ULONG now = (ULONG)tm;
      if (lastClickWnd == this &&
      (now - lastTime) <= multiClickTime &&
      abs(x - lastClickX) <= multiClickMaxX &&
      abs(y - lastClickY) <= multiClickMaxY) {
      clickCount++;
      }
      else {
      clickCount = 1;
      }
      [960] lastClickWnd = this;
      lastTime = now;
      lastClickX = x;
      lastClickY = y;
      m_dragged = FALSE;

      MSG* msg = CreateMessage(lastMessage, flags, MAKELPARAM(x, y));
      SendMouseEvent(java_awt_event_MouseEvent_MOUSE_PRESSED, tm, x, y,
      GetJavaModifiers(flags, button), clickCount, 0, msg);

      [970] return mrConsume;
      }

      MsgRouting AwtComponent::WmMouseUp(UINT flags, int x, int y, int button)
      {
      MSG* msg = CreateMessage(lastMessage, flags, MAKELPARAM(x, y));
      SendMouseEvent(java_awt_event_MouseEvent_MOUSE_RELEASED, nowMillis(),
      x, y, GetJavaModifiers(flags, button), clickCount,
      (button == RIGHT_BUTTON? 1 : 0), msg);

      [980] // If no movement, then report a click following the button release
      //
      if (!m_dragged) {
      SendMouseEvent(java_awt_event_MouseEvent_MOUSE_CLICKED,
      nowMillis(), x, y,
      GetJavaModifiers(flags, button), clickCount, 0);
      }
      m_dragged = FALSE;

      return mrConsume;
      [990] }

      MsgRouting AwtComponent::WmMouseMove(UINT flags, int x, int y)
      {
      static AwtComponent* lastComp = NULL;
      static int lastX = 0;
      static int lastY = 0;

      // Only report mouse move and drag events if a move or drag actually
      // happened -- Windows sends a WM_MOUSEMOVE in case the app wants to
      [1000] // modify the cursor.
      if (lastComp != this || x != lastX || y != lastY) {
      lastComp = this;
      lastX = x;
      lastY = y;

      long id;
      if ((flags&(MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))) {
      if (!m_dragged) {
      // eat the first move in case it is only a click
      [1010] m_dragged = TRUE;
      return mrConsume;
      }
      id = java_awt_event_MouseEvent_MOUSE_DRAGGED;
      } else {
      id = java_awt_event_MouseEvent_MOUSE_MOVED;
      }

      MSG* msg = CreateMessage(lastMessage, flags, MAKELPARAM(x, y));
      SendMouseEvent(id, nowMillis(), x, y,
      [1020] GetJavaModifiers(flags, 0), 0, 0, msg);
      } else {
      ::SetCursor(GetCursor(TRUE));
      }
      return mrConsume;
      [1025] }
      (Review ID: 20731)
      ======================================================================

            ehawkessunw Eric Hawkes (Inactive)
            johsunw Joon Oh (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: