Bug 1023041 - Part 2: Generate correct event when dragging touch caret. r=roc
authorMorris Tseng <mtseng@mozilla.com>
Mon, 04 Aug 2014 00:24:00 -0400
changeset 197966 feb9b9683e979563cc1f5e100887cad10684cf2e
parent 197965 24266caa6b44765f2b7be5b1a48dc63a35917d5f
child 197967 4361cb2e3378d0f1a66308c3cc33adb4319c2417
push id27256
push userkwierso@gmail.com
push dateWed, 06 Aug 2014 00:06:20 +0000
treeherdermozilla-central@6cbdd4d523a7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1023041
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1023041 - Part 2: Generate correct event when dragging touch caret. r=roc
layout/base/TouchCaret.cpp
layout/base/TouchCaret.h
--- a/layout/base/TouchCaret.cpp
+++ b/layout/base/TouchCaret.cpp
@@ -460,16 +460,32 @@ TouchCaret::LaunchExpirationTimer()
 void
 TouchCaret::CancelExpirationTimer()
 {
   if (mTouchCaretExpirationTimer) {
     mTouchCaretExpirationTimer->Cancel();
   }
 }
 
+void
+TouchCaret::SetSelectionDragState(bool aState)
+{
+  nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
+  if (!presShell) {
+    return;
+  }
+
+  nsRefPtr<nsCaret> caret = presShell->GetCaret();
+  nsISelection* caretSelection = caret->GetCaretDOMSelection();
+  nsRect focusRect;
+  nsIFrame* caretFocusFrame = caret->GetGeometry(caretSelection, &focusRect);
+  nsRefPtr<nsFrameSelection> fs = caretFocusFrame->GetFrameSelection();
+  fs->SetDragState(aState);
+}
+
 nsEventStatus
 TouchCaret::HandleEvent(WidgetEvent* aEvent)
 {
   MOZ_ASSERT(NS_IsMainThread());
   nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
   if (!presShell) {
     return nsEventStatus_eIgnore;
   }
@@ -623,16 +639,17 @@ TouchCaret::HandleMouseUpEvent(WidgetMou
   nsEventStatus status = nsEventStatus_eIgnore;
 
   switch (mState) {
     case TOUCHCARET_NONE:
       break;
 
     case TOUCHCARET_MOUSEDRAG_ACTIVE:
       if (aEvent->button == WidgetMouseEvent::eLeftButton) {
+        SetSelectionDragState(false);
         LaunchExpirationTimer();
         SetState(TOUCHCARET_NONE);
         status = nsEventStatus_eConsumeNoDefault;
       }
       break;
 
     case TOUCHCARET_TOUCHDRAG_ACTIVE:
     case TOUCHCARET_TOUCHDRAG_INACTIVE:
@@ -667,16 +684,17 @@ TouchCaret::HandleTouchUpEvent(WidgetTou
 
     case TOUCHCARET_MOUSEDRAG_ACTIVE:
       // Consume touch event in mouse sequence.
       status = nsEventStatus_eConsumeNoDefault;
       break;
 
     case TOUCHCARET_TOUCHDRAG_ACTIVE:
       if (mTouchesId.Length() == 0) {
+        SetSelectionDragState(false);
         // No more finger on the screen.
         SetState(TOUCHCARET_NONE);
         LaunchExpirationTimer();
       } else {
         // Still has finger touching on the screen.
         if (aEvent->touches[0]->mIdentifier == mActiveTouchId) {
           // Remove finger from the touch caret.
           SetState(TOUCHCARET_TOUCHDRAG_INACTIVE);
@@ -712,16 +730,17 @@ TouchCaret::HandleMouseDownEvent(WidgetM
 
   nsEventStatus status = nsEventStatus_eIgnore;
 
   switch (mState) {
     case TOUCHCARET_NONE:
       if (aEvent->button == WidgetMouseEvent::eLeftButton) {
         nsPoint point = GetEventPosition(aEvent);
         if (IsOnTouchCaret(point)) {
+          SetSelectionDragState(true);
           // Cache distence of the event point to the center of touch caret.
           mCaretCenterToDownPointOffsetY = GetCaretYCenterPosition() - point.y;
           // Enter TOUCHCARET_MOUSEDRAG_ACTIVE state and cancel the timer.
           SetState(TOUCHCARET_MOUSEDRAG_ACTIVE);
           CancelExpirationTimer();
           status = nsEventStatus_eConsumeNoDefault;
         } else {
           // Set touch caret invisible if HisTest fails. Bypass event.
@@ -764,16 +783,17 @@ TouchCaret::HandleTouchDownEvent(WidgetT
         status = nsEventStatus_eIgnore;
       } else {
         // Loop over all the touches and see if any of them is on the touch
         // caret.
         for (size_t i = 0; i < aEvent->touches.Length(); ++i) {
           int32_t touchId = aEvent->touches[i]->Identifier();
           nsPoint point = GetEventPosition(aEvent, touchId);
           if (IsOnTouchCaret(point)) {
+            SetSelectionDragState(true);
             // Touch start position is contained in touch caret.
             mActiveTouchId = touchId;
             // Cache distance of the event point to the center of touch caret.
             mCaretCenterToDownPointOffsetY = GetCaretYCenterPosition() - point.y;
             // Enter TOUCHCARET_TOUCHDRAG_ACTIVE state and cancel the timer.
             SetState(TOUCHCARET_TOUCHDRAG_ACTIVE);
             CancelExpirationTimer();
             status = nsEventStatus_eConsumeNoDefault;
--- a/layout/base/TouchCaret.h
+++ b/layout/base/TouchCaret.h
@@ -144,16 +144,25 @@ private:
    * @param aIdentifier the mIdentifier of the touch which is to be converted.
    * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
    * for some reason the coordinates for the touch are not known (e.g.,
    * the mIdentifier touch is not found).
    */
   nsPoint GetEventPosition(WidgetTouchEvent* aEvent, int32_t aIdentifier);
 
   /**
+   * Set mouse down state in nsFrameSelection, we'll set state to true when
+   * user start dragging caret and set state to false when user release the
+   * caret. The reason for setting this state is it will fire drag reason
+   * when moving caret and fire mouseup reason when releasing caret. So that
+   * the display behavior of copy/paste menu becomes more reasonable.
+   */
+  void SetSelectionDragState(bool aState);
+
+  /**
    * Get the coordinates of a given mouse event, relative to canvas frame.
    * @param aEvent the event
    * @return the point, or (NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE) if
    * for some reason the coordinates for the mouse are not known.
    */
   nsPoint GetEventPosition(WidgetMouseEvent* aEvent);
 
   /**