From 98661461cfe256a06fafe9abc4c67caf26f9ae20 Mon Sep 17 00:00:00 2001 From: "aaronleventhal@moonset.net" Date: Thu, 19 Apr 2007 06:53:34 -0700 Subject: [PATCH] Bug 352205. Swallow duplicate caret move events. r=ginn.chen --- accessible/src/base/nsCaretAccessible.cpp | 27 +++++++++++++++++++---- accessible/src/base/nsCaretAccessible.h | 4 +++- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/accessible/src/base/nsCaretAccessible.cpp b/accessible/src/base/nsCaretAccessible.cpp index 3c953ef87574..ed912c9713db 100644 --- a/accessible/src/base/nsCaretAccessible.cpp +++ b/accessible/src/base/nsCaretAccessible.cpp @@ -56,14 +56,16 @@ NS_IMPL_ISUPPORTS_INHERITED2(nsCaretAccessible, nsLeafAccessible, nsIAccessibleCaret, nsISelectionListener) nsCaretAccessible::nsCaretAccessible(nsIDOMNode* aDocumentNode, nsIWeakReference* aShell, nsRootAccessible *aRootAccessible): -nsLeafAccessible(aDocumentNode, aShell), mVisible(PR_TRUE), mCurrentDOMNode(nsnull), mRootAccessible(aRootAccessible) +nsLeafAccessible(aDocumentNode, aShell), mVisible(PR_TRUE), mLastCaretOffset(-1), mLastNodeWithCaret(nsnull), +mSelectionControllerNode(nsnull), mRootAccessible(aRootAccessible) { } NS_IMETHODIMP nsCaretAccessible::Shutdown() { mDomSelectionWeak = nsnull; - mCurrentDOMNode = nsnull; + mLastNodeWithCaret = nsnull; + mSelectionControllerNode = nsnull; RemoveSelectionListener(); return NS_OK; } @@ -81,7 +83,8 @@ NS_IMETHODIMP nsCaretAccessible::RemoveSelectionListener() NS_IMETHODIMP nsCaretAccessible::AttachNewSelectionListener(nsIDOMNode *aCurrentNode) { - mCurrentDOMNode = aCurrentNode; + mSelectionControllerNode = aCurrentNode; + mLastNodeWithCaret = nsnull; // When focus moves such that the caret is part of a new frame selection // this removes the old selection listener and attaches a new one for the current focus @@ -123,7 +126,7 @@ NS_IMETHODIMP nsCaretAccessible::AttachNewSelectionListener(nsIDOMNode *aCurrent NS_IMETHODIMP nsCaretAccessible::NotifySelectionChanged(nsIDOMDocument *aDoc, nsISelection *aSel, PRInt16 aReason) { - nsCOMPtr presShell = GetPresShellFor(mCurrentDOMNode); + nsCOMPtr presShell = GetPresShellFor(mSelectionControllerNode); nsCOMPtr domSel(do_QueryReferent(mDomSelectionWeak)); if (!presShell || domSel != aSel) return NS_OK; // Only listening to selection changes in currently focused frame @@ -181,8 +184,11 @@ NS_IMETHODIMP nsCaretAccessible::NotifySelectionChanged(nsIDOMDocument *aDoc, ns nsCOMPtr focusNode; domSel->GetFocusNode(getter_AddRefs(focusNode)); if (!focusNode) { + mLastNodeWithCaret = nsnull; return NS_OK; // No selection } + nsCOMPtr nodeWithCaret = focusNode; + nsCOMPtr textAcc; while (focusNode) { // Make sure to get the correct starting node for selection events inside XBL content trees @@ -206,6 +212,19 @@ NS_IMETHODIMP nsCaretAccessible::NotifySelectionChanged(nsIDOMDocument *aDoc, ns NS_ASSERTION(textAcc, "No nsIAccessibleText for caret move event!"); // No nsIAccessibleText for caret move event! NS_ENSURE_TRUE(textAcc, NS_ERROR_FAILURE); + PRInt32 caretOffset; + textAcc->GetCaretOffset(&caretOffset); + + if (nodeWithCaret == mLastNodeWithCaret && caretOffset == mLastCaretOffset) { + PRInt32 selectionCount; + textAcc->GetSelectionCount(&selectionCount); // Don't swallow similar events when selecting text + if (!selectionCount) { + return NS_OK; // Swallow duplicate caret event + } + } + mLastCaretOffset = caretOffset; + mLastNodeWithCaret = nodeWithCaret; + return mRootAccessible->FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, focusNode, nsnull, PR_FALSE); } diff --git a/accessible/src/base/nsCaretAccessible.h b/accessible/src/base/nsCaretAccessible.h index 3ac49ac29535..4bdbc24b1567 100644 --- a/accessible/src/base/nsCaretAccessible.h +++ b/accessible/src/base/nsCaretAccessible.h @@ -91,7 +91,9 @@ public: private: nsRect mCaretRect; PRBool mVisible; - nsCOMPtr mCurrentDOMNode; + PRInt32 mLastCaretOffset; + nsCOMPtr mLastNodeWithCaret; + nsCOMPtr mSelectionControllerNode; // mListener is not a com pointer. It's a copy of the listener in the nsRootAccessible owner. //See nsRootAccessible.h for details of the lifetime if this listener nsRootAccessible *mRootAccessible;