From 2d35ca6701178a4d2fe73c733e29b7c6ea4806fd Mon Sep 17 00:00:00 2001 From: "rods%netscape.com" Date: Wed, 20 Dec 2000 23:25:40 +0000 Subject: [PATCH] When clicking away from the dropdown, it wasn't resetting itself correctly. If only the mouse was being used for selection, then it needs to reset itself to the state before dropping down if arrow keys had been used then it needs to keep that selection The combobox chaches the current selection, so when arrow keys are used it has the correct selection when the mouse is used it holds the old selection. So therefore, we can compare against it to determine what to do. Bug 63247 r=waqar sr=hyatt git-svn-id: svn://10.0.0.236/trunk@83918 18797224-902f-48f8-a5cc-f745e15eee43 --- .../layout/forms/nsComboboxControlFrame.cpp | 7 +++++ mozilla/layout/forms/nsComboboxControlFrame.h | 1 + .../layout/forms/nsIComboboxControlFrame.h | 17 +++++++++++ mozilla/layout/forms/nsListControlFrame.cpp | 28 ++++++++++++++++--- .../forms/public/nsIComboboxControlFrame.h | 17 +++++++++++ .../html/forms/src/nsComboboxControlFrame.cpp | 7 +++++ .../html/forms/src/nsComboboxControlFrame.h | 1 + .../html/forms/src/nsListControlFrame.cpp | 28 ++++++++++++++++--- 8 files changed, 98 insertions(+), 8 deletions(-) diff --git a/mozilla/layout/forms/nsComboboxControlFrame.cpp b/mozilla/layout/forms/nsComboboxControlFrame.cpp index ce76f428e55..9030326ce31 100644 --- a/mozilla/layout/forms/nsComboboxControlFrame.cpp +++ b/mozilla/layout/forms/nsComboboxControlFrame.cpp @@ -1939,6 +1939,13 @@ nsComboboxControlFrame::SelectionChanged() return rv; } +NS_IMETHODIMP +nsComboboxControlFrame::GetIndexOfDisplayArea(PRInt32* aSelectedIndex) +{ + NS_ENSURE_ARG_POINTER(aSelectedIndex); + *aSelectedIndex = mSelectedIndex; + return NS_OK; +} //---------------------------------------------------------------------- // nsISelectControlFrame diff --git a/mozilla/layout/forms/nsComboboxControlFrame.h b/mozilla/layout/forms/nsComboboxControlFrame.h index 4584222a836..86607ea0544 100644 --- a/mozilla/layout/forms/nsComboboxControlFrame.h +++ b/mozilla/layout/forms/nsComboboxControlFrame.h @@ -166,6 +166,7 @@ public: NS_IMETHOD UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate, PRInt32 aNewIndex); NS_IMETHOD AbsolutelyPositionDropDown(); NS_IMETHOD GetAbsoluteRect(nsRect* aRect); + NS_IMETHOD GetIndexOfDisplayArea(PRInt32* aSelectedIndex); // nsISelectControlFrame NS_IMETHOD AddOption(nsIPresContext* aPresContext, PRInt32 index); diff --git a/mozilla/layout/forms/nsIComboboxControlFrame.h b/mozilla/layout/forms/nsIComboboxControlFrame.h index 38dd1cb024c..81ac099086e 100644 --- a/mozilla/layout/forms/nsIComboboxControlFrame.h +++ b/mozilla/layout/forms/nsIComboboxControlFrame.h @@ -115,6 +115,23 @@ public: */ NS_IMETHOD SetFrameConstructor(nsCSSFrameConstructor *aConstructor) = 0; + /** + * This returns the index of the item that is currently being displayed + * in the display area. It may differ from what the currently Selected index + * is in in the dropdown. + * + * Detailed explanation: + * When the dropdown is dropped down via a mouse click and the user moves the mouse + * up and down without clicking, the currently selected item is being tracking inside + * the dropdown, but the combobox is not being updated. When the user selects items + * with the arrow keys, the combobox is being updated. So when the user clicks outside + * the dropdown and it needs to roll up it has to decide whether to keep the current + * selection or not. This method is used to get the current index in the combobox to + * compare it to the current index in the dropdown to see if the combox has been updated + * and that way it knows whether to "cancel" the the current selection residing in the + * dropdown. Or whether to leave the selection alone. + */ + NS_IMETHOD GetIndexOfDisplayArea(PRInt32* aSelectedIndex) = 0; }; #endif diff --git a/mozilla/layout/forms/nsListControlFrame.cpp b/mozilla/layout/forms/nsListControlFrame.cpp index 2f0f6aea3ba..0f9b93694a5 100644 --- a/mozilla/layout/forms/nsListControlFrame.cpp +++ b/mozilla/layout/forms/nsListControlFrame.cpp @@ -2847,10 +2847,30 @@ nsListControlFrame::AboutToDropDown() NS_IMETHODIMP nsListControlFrame::AboutToRollup() { - // XXX By uncommenting this line below the "act" of rolling up - // will reset the the contents of the combobox to it's original contents - // (i.e. the contents before it was dropped down - ResetSelectedItem(); + // XXX To have clicking outside the combobox ALWAYS reset the contents to the + // state before it was dropped, remove the all the code in the "if" below and replace it + // with just the call to ResetSelectedItem() + // + // + // When the dropdown is dropped down via a mouse click and the user moves the mouse + // up and down without clicking, the currently selected item is being tracking inside + // the dropdown, but the combobox is not being updated. When the user selects items + // with the arrow keys, the combobox is being updated. So when the user clicks outside + // the dropdown and it needs to roll up it has to decide whether to keep the current + // selection or not. The GetIndexOfDisplayArea method is used to get the current index + // in the combobox to compare it to the current index in the dropdown to see if the combox + // has been updated and that way it knows whether to "cancel" the the current selection + // residing in the dropdown. Or whether to leave the selection alone. + if (IsInDropDownMode() == PR_TRUE) { + PRInt32 index; + mComboboxFrame->GetIndexOfDisplayArea(&index); + // if the indexes do NOT match then the selection in the combobox + // was never updated, and therefore we should reset the the selection back to + // whatever it was before it was dropped down. + if (index != mSelectedIndex) { + ResetSelectedItem(); + } + } return NS_OK; } diff --git a/mozilla/layout/html/forms/public/nsIComboboxControlFrame.h b/mozilla/layout/html/forms/public/nsIComboboxControlFrame.h index 38dd1cb024c..81ac099086e 100644 --- a/mozilla/layout/html/forms/public/nsIComboboxControlFrame.h +++ b/mozilla/layout/html/forms/public/nsIComboboxControlFrame.h @@ -115,6 +115,23 @@ public: */ NS_IMETHOD SetFrameConstructor(nsCSSFrameConstructor *aConstructor) = 0; + /** + * This returns the index of the item that is currently being displayed + * in the display area. It may differ from what the currently Selected index + * is in in the dropdown. + * + * Detailed explanation: + * When the dropdown is dropped down via a mouse click and the user moves the mouse + * up and down without clicking, the currently selected item is being tracking inside + * the dropdown, but the combobox is not being updated. When the user selects items + * with the arrow keys, the combobox is being updated. So when the user clicks outside + * the dropdown and it needs to roll up it has to decide whether to keep the current + * selection or not. This method is used to get the current index in the combobox to + * compare it to the current index in the dropdown to see if the combox has been updated + * and that way it knows whether to "cancel" the the current selection residing in the + * dropdown. Or whether to leave the selection alone. + */ + NS_IMETHOD GetIndexOfDisplayArea(PRInt32* aSelectedIndex) = 0; }; #endif diff --git a/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp b/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp index ce76f428e55..9030326ce31 100644 --- a/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp @@ -1939,6 +1939,13 @@ nsComboboxControlFrame::SelectionChanged() return rv; } +NS_IMETHODIMP +nsComboboxControlFrame::GetIndexOfDisplayArea(PRInt32* aSelectedIndex) +{ + NS_ENSURE_ARG_POINTER(aSelectedIndex); + *aSelectedIndex = mSelectedIndex; + return NS_OK; +} //---------------------------------------------------------------------- // nsISelectControlFrame diff --git a/mozilla/layout/html/forms/src/nsComboboxControlFrame.h b/mozilla/layout/html/forms/src/nsComboboxControlFrame.h index 4584222a836..86607ea0544 100644 --- a/mozilla/layout/html/forms/src/nsComboboxControlFrame.h +++ b/mozilla/layout/html/forms/src/nsComboboxControlFrame.h @@ -166,6 +166,7 @@ public: NS_IMETHOD UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate, PRInt32 aNewIndex); NS_IMETHOD AbsolutelyPositionDropDown(); NS_IMETHOD GetAbsoluteRect(nsRect* aRect); + NS_IMETHOD GetIndexOfDisplayArea(PRInt32* aSelectedIndex); // nsISelectControlFrame NS_IMETHOD AddOption(nsIPresContext* aPresContext, PRInt32 index); diff --git a/mozilla/layout/html/forms/src/nsListControlFrame.cpp b/mozilla/layout/html/forms/src/nsListControlFrame.cpp index 2f0f6aea3ba..0f9b93694a5 100644 --- a/mozilla/layout/html/forms/src/nsListControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsListControlFrame.cpp @@ -2847,10 +2847,30 @@ nsListControlFrame::AboutToDropDown() NS_IMETHODIMP nsListControlFrame::AboutToRollup() { - // XXX By uncommenting this line below the "act" of rolling up - // will reset the the contents of the combobox to it's original contents - // (i.e. the contents before it was dropped down - ResetSelectedItem(); + // XXX To have clicking outside the combobox ALWAYS reset the contents to the + // state before it was dropped, remove the all the code in the "if" below and replace it + // with just the call to ResetSelectedItem() + // + // + // When the dropdown is dropped down via a mouse click and the user moves the mouse + // up and down without clicking, the currently selected item is being tracking inside + // the dropdown, but the combobox is not being updated. When the user selects items + // with the arrow keys, the combobox is being updated. So when the user clicks outside + // the dropdown and it needs to roll up it has to decide whether to keep the current + // selection or not. The GetIndexOfDisplayArea method is used to get the current index + // in the combobox to compare it to the current index in the dropdown to see if the combox + // has been updated and that way it knows whether to "cancel" the the current selection + // residing in the dropdown. Or whether to leave the selection alone. + if (IsInDropDownMode() == PR_TRUE) { + PRInt32 index; + mComboboxFrame->GetIndexOfDisplayArea(&index); + // if the indexes do NOT match then the selection in the combobox + // was never updated, and therefore we should reset the the selection back to + // whatever it was before it was dropped down. + if (index != mSelectedIndex) { + ResetSelectedItem(); + } + } return NS_OK; }