Patch for bug 35296: SetCaretEnabled() takes too long
Patch by Leon.Zhang@sun.com r=sfraser, sr=kin
This commit is contained in:
Родитель
e21a8221f4
Коммит
b7df6947aa
|
@ -746,11 +746,30 @@ nsEditor::EndPlaceHolderTransaction()
|
||||||
NS_PRECONDITION(mPlaceHolderBatch > 0, "zero or negative placeholder batch count when ending batch!");
|
NS_PRECONDITION(mPlaceHolderBatch > 0, "zero or negative placeholder batch count when ending batch!");
|
||||||
if (mPlaceHolderBatch == 1)
|
if (mPlaceHolderBatch == 1)
|
||||||
{
|
{
|
||||||
|
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
|
||||||
|
nsCOMPtr<nsICaret> caret;
|
||||||
|
if (!ps)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
nsresult rv = ps->GetCaret(getter_AddRefs(caret));
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
// optimizing drawcaret starts
|
||||||
|
if (caret) {
|
||||||
|
caret->SetOptimizeDrawCaret(PR_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
// time to turn off the batch
|
// time to turn off the batch
|
||||||
EndUpdateViewBatch();
|
EndUpdateViewBatch();
|
||||||
// make sure selection is in view
|
// make sure selection is in view
|
||||||
ScrollSelectionIntoView(PR_FALSE);
|
ScrollSelectionIntoView(PR_FALSE);
|
||||||
|
|
||||||
|
// optimizing drawcaret stops
|
||||||
|
if (caret) {
|
||||||
|
caret->SetOptimizeDrawCaret(PR_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
if (mSelState)
|
if (mSelState)
|
||||||
{
|
{
|
||||||
// we saved the selection state, but never got to hand it to placeholder
|
// we saved the selection state, but never got to hand it to placeholder
|
||||||
|
@ -4340,15 +4359,6 @@ nsresult nsEditor::EndUpdateViewBatch()
|
||||||
if (!caret)
|
if (!caret)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
StCaretHider caretHider(caret);
|
|
||||||
|
|
||||||
nsCOMPtr<nsISelection>selection;
|
|
||||||
nsresult selectionResult = GetSelection(getter_AddRefs(selection));
|
|
||||||
if (NS_SUCCEEDED(selectionResult) && selection) {
|
|
||||||
nsCOMPtr<nsISelectionPrivate>selPrivate(do_QueryInterface(selection));
|
|
||||||
selPrivate->EndBatchChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mViewManager)
|
if (mViewManager)
|
||||||
{
|
{
|
||||||
mUpdateCount--;
|
mUpdateCount--;
|
||||||
|
@ -4361,6 +4371,8 @@ nsresult nsEditor::EndUpdateViewBatch()
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
|
StCaretHider caretHider(caret);
|
||||||
|
|
||||||
// Make sure we enable reflowing before we call
|
// Make sure we enable reflowing before we call
|
||||||
// mViewManager->EndUpdateViewBatch(). This will make sure that any
|
// mViewManager->EndUpdateViewBatch(). This will make sure that any
|
||||||
// new updates caused by a reflow, that may happen during the
|
// new updates caused by a reflow, that may happen during the
|
||||||
|
@ -4386,6 +4398,13 @@ nsresult nsEditor::EndUpdateViewBatch()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsISelection>selection;
|
||||||
|
nsresult selectionResult = GetSelection(getter_AddRefs(selection));
|
||||||
|
if (NS_SUCCEEDED(selectionResult) && selection) {
|
||||||
|
nsCOMPtr<nsISelectionPrivate>selPrivate(do_QueryInterface(selection));
|
||||||
|
selPrivate->EndBatchChanges();
|
||||||
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -334,10 +334,6 @@ nsHTMLEditRules::BeforeEdit(PRInt32 action, nsIEditor::EDirection aDirection)
|
||||||
nsrange->NSDetach(); // ditto for mUtilRange.
|
nsrange->NSDetach(); // ditto for mUtilRange.
|
||||||
}
|
}
|
||||||
|
|
||||||
// turn off caret
|
|
||||||
nsCOMPtr<nsISelectionController> selCon;
|
|
||||||
mHTMLEditor->GetSelectionController(getter_AddRefs(selCon));
|
|
||||||
if (selCon) selCon->SetCaretEnabled(PR_FALSE);
|
|
||||||
// check that selection is in subtree defined by body node
|
// check that selection is in subtree defined by body node
|
||||||
ConfirmSelectionInBody();
|
ConfirmSelectionInBody();
|
||||||
// let rules remember the top level action
|
// let rules remember the top level action
|
||||||
|
@ -365,10 +361,6 @@ nsHTMLEditRules::AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection)
|
||||||
// free up selectionState range item
|
// free up selectionState range item
|
||||||
(mHTMLEditor->mRangeUpdater).DropRangeItem(&mRangeItem);
|
(mHTMLEditor->mRangeUpdater).DropRangeItem(&mRangeItem);
|
||||||
|
|
||||||
// turn on caret
|
|
||||||
nsCOMPtr<nsISelectionController> selCon;
|
|
||||||
mHTMLEditor->GetSelectionController(getter_AddRefs(selCon));
|
|
||||||
if (selCon) selCon->SetCaretEnabled(PR_TRUE);
|
|
||||||
/* After inserting text the cursor Bidi level must be set to the level of the inserted text.
|
/* After inserting text the cursor Bidi level must be set to the level of the inserted text.
|
||||||
* This is difficult, because we cannot know what the level is until after the Bidi algorithm
|
* This is difficult, because we cannot know what the level is until after the Bidi algorithm
|
||||||
* is applied to the whole paragraph.
|
* is applied to the whole paragraph.
|
||||||
|
|
|
@ -92,6 +92,7 @@ nsCaret::nsCaret()
|
||||||
, mDrawn(PR_FALSE)
|
, mDrawn(PR_FALSE)
|
||||||
, mReadOnly(PR_FALSE)
|
, mReadOnly(PR_FALSE)
|
||||||
, mShowDuringSelection(PR_FALSE)
|
, mShowDuringSelection(PR_FALSE)
|
||||||
|
, mOptimizeDrawCaret(PR_FALSE)
|
||||||
, mCachedOffsetValid(PR_FALSE)
|
, mCachedOffsetValid(PR_FALSE)
|
||||||
, mLastCaretFrame(nsnull)
|
, mLastCaretFrame(nsnull)
|
||||||
, mLastCaretView(nsnull)
|
, mLastCaretView(nsnull)
|
||||||
|
@ -445,6 +446,11 @@ NS_IMETHODIMP nsCaret::DrawAtPosition(nsIDOMNode* aNode, PRInt32 aOffset)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsCaret::SetOptimizeDrawCaret(PRBool aOptimzeDrawCaret)
|
||||||
|
{
|
||||||
|
mOptimizeDrawCaret = aOptimzeDrawCaret;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef XP_MAC
|
#ifdef XP_MAC
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
@ -1069,19 +1075,14 @@ void nsCaret::GetCaretRectAndInvert()
|
||||||
{
|
{
|
||||||
nsRect caretRect = frameRect;
|
nsRect caretRect = frameRect;
|
||||||
|
|
||||||
// if mCachedOffsetValid, apply cached FrameOffset, else compute it again
|
// if use cache and cache is ready, apply it, else refresh it
|
||||||
if (!mCachedOffsetValid)
|
if (!mOptimizeDrawCaret || !mCachedOffsetValid) {
|
||||||
{
|
mLastCaretFrame->GetPointFromOffset(presContext, mRendContext,mLastContentOffset, &mCachedFrameOffset);
|
||||||
mLastCaretFrame->GetPointFromOffset(presContext, mRendContext, mLastContentOffset, &mCachedFrameOffset);
|
mCachedOffsetValid = mOptimizeDrawCaret;
|
||||||
// XXX: The following line was commented out to disable the
|
|
||||||
// offset caching code because it causes bad caret
|
|
||||||
// placement. (bug 194774)
|
|
||||||
//
|
|
||||||
// mCachedOffsetValid = PR_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
caretRect += mCachedFrameOffset;
|
caretRect += mCachedFrameOffset;
|
||||||
|
|
||||||
if (mCaretTwipsWidth < 0) // need to re-compute the pixel width
|
if (mCaretTwipsWidth < 0) // need to re-compute the pixel width
|
||||||
{
|
{
|
||||||
float tDevUnitsToTwips = 15;
|
float tDevUnitsToTwips = 15;
|
||||||
|
|
|
@ -65,6 +65,8 @@ class nsCaret : public nsICaret,
|
||||||
NS_IMETHOD SetVisibilityDuringSelection(PRBool aVisibility);
|
NS_IMETHOD SetVisibilityDuringSelection(PRBool aVisibility);
|
||||||
NS_IMETHOD DrawAtPosition(nsIDOMNode* aNode, PRInt32 aOffset);
|
NS_IMETHOD DrawAtPosition(nsIDOMNode* aNode, PRInt32 aOffset);
|
||||||
|
|
||||||
|
NS_IMETHOD SetOptimizeDrawCaret(PRBool aOptimzeDrawCaret);
|
||||||
|
|
||||||
//nsISelectionListener interface
|
//nsISelectionListener interface
|
||||||
NS_IMETHOD NotifySelectionChanged(nsIDOMDocument *aDoc, nsISelection *aSel, short aReason);
|
NS_IMETHOD NotifySelectionChanged(nsIDOMDocument *aDoc, nsISelection *aSel, short aReason);
|
||||||
|
|
||||||
|
@ -103,9 +105,10 @@ protected:
|
||||||
PRPackedBool mReadOnly; // it the caret in readonly state (draws differently)
|
PRPackedBool mReadOnly; // it the caret in readonly state (draws differently)
|
||||||
PRPackedBool mShowDuringSelection; // show when text is selected
|
PRPackedBool mShowDuringSelection; // show when text is selected
|
||||||
|
|
||||||
PRPackedBool mCachedOffsetValid; //whether the cached frame offset is valid
|
PRPackedBool mOptimizeDrawCaret; // flag for optimizing draw caret
|
||||||
nsPoint mCachedFrameOffset; //cached frame offset
|
PRPackedBool mCachedOffsetValid; // whether the cached frame offset is valid
|
||||||
|
nsPoint mCachedFrameOffset; // cached frame offset
|
||||||
|
|
||||||
nsRect mCaretRect; // the last caret rect
|
nsRect mCaretRect; // the last caret rect
|
||||||
nsIFrame* mLastCaretFrame; // store the frame the caret was last drawn in.
|
nsIFrame* mLastCaretFrame; // store the frame the caret was last drawn in.
|
||||||
nsIView* mLastCaretView; // last view that we used for drawing. Cached so we can tell when we need to make a new RC
|
nsIView* mLastCaretView; // last view that we used for drawing. Cached so we can tell when we need to make a new RC
|
||||||
|
|
|
@ -125,6 +125,11 @@ public:
|
||||||
**/
|
**/
|
||||||
NS_IMETHOD DrawAtPosition(nsIDOMNode* aNode, PRInt32 aOffset) = 0;
|
NS_IMETHOD DrawAtPosition(nsIDOMNode* aNode, PRInt32 aOffset) = 0;
|
||||||
|
|
||||||
|
/** SetOptimizeDrawCaret
|
||||||
|
* To start or stop process of optimizing draw caret
|
||||||
|
*/
|
||||||
|
NS_IMETHOD SetOptimizeDrawCaret(PRBool aOptimzeDrawCaret) = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
@ -125,6 +125,11 @@ public:
|
||||||
**/
|
**/
|
||||||
NS_IMETHOD DrawAtPosition(nsIDOMNode* aNode, PRInt32 aOffset) = 0;
|
NS_IMETHOD DrawAtPosition(nsIDOMNode* aNode, PRInt32 aOffset) = 0;
|
||||||
|
|
||||||
|
/** SetOptimizeDrawCaret
|
||||||
|
* To start or stop process of optimizing draw caret
|
||||||
|
*/
|
||||||
|
NS_IMETHOD SetOptimizeDrawCaret(PRBool aOptimzeDrawCaret) = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
@ -92,6 +92,7 @@ nsCaret::nsCaret()
|
||||||
, mDrawn(PR_FALSE)
|
, mDrawn(PR_FALSE)
|
||||||
, mReadOnly(PR_FALSE)
|
, mReadOnly(PR_FALSE)
|
||||||
, mShowDuringSelection(PR_FALSE)
|
, mShowDuringSelection(PR_FALSE)
|
||||||
|
, mOptimizeDrawCaret(PR_FALSE)
|
||||||
, mCachedOffsetValid(PR_FALSE)
|
, mCachedOffsetValid(PR_FALSE)
|
||||||
, mLastCaretFrame(nsnull)
|
, mLastCaretFrame(nsnull)
|
||||||
, mLastCaretView(nsnull)
|
, mLastCaretView(nsnull)
|
||||||
|
@ -445,6 +446,11 @@ NS_IMETHODIMP nsCaret::DrawAtPosition(nsIDOMNode* aNode, PRInt32 aOffset)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsCaret::SetOptimizeDrawCaret(PRBool aOptimzeDrawCaret)
|
||||||
|
{
|
||||||
|
mOptimizeDrawCaret = aOptimzeDrawCaret;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef XP_MAC
|
#ifdef XP_MAC
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
@ -1069,19 +1075,14 @@ void nsCaret::GetCaretRectAndInvert()
|
||||||
{
|
{
|
||||||
nsRect caretRect = frameRect;
|
nsRect caretRect = frameRect;
|
||||||
|
|
||||||
// if mCachedOffsetValid, apply cached FrameOffset, else compute it again
|
// if use cache and cache is ready, apply it, else refresh it
|
||||||
if (!mCachedOffsetValid)
|
if (!mOptimizeDrawCaret || !mCachedOffsetValid) {
|
||||||
{
|
mLastCaretFrame->GetPointFromOffset(presContext, mRendContext,mLastContentOffset, &mCachedFrameOffset);
|
||||||
mLastCaretFrame->GetPointFromOffset(presContext, mRendContext, mLastContentOffset, &mCachedFrameOffset);
|
mCachedOffsetValid = mOptimizeDrawCaret;
|
||||||
// XXX: The following line was commented out to disable the
|
|
||||||
// offset caching code because it causes bad caret
|
|
||||||
// placement. (bug 194774)
|
|
||||||
//
|
|
||||||
// mCachedOffsetValid = PR_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
caretRect += mCachedFrameOffset;
|
caretRect += mCachedFrameOffset;
|
||||||
|
|
||||||
if (mCaretTwipsWidth < 0) // need to re-compute the pixel width
|
if (mCaretTwipsWidth < 0) // need to re-compute the pixel width
|
||||||
{
|
{
|
||||||
float tDevUnitsToTwips = 15;
|
float tDevUnitsToTwips = 15;
|
||||||
|
|
|
@ -65,6 +65,8 @@ class nsCaret : public nsICaret,
|
||||||
NS_IMETHOD SetVisibilityDuringSelection(PRBool aVisibility);
|
NS_IMETHOD SetVisibilityDuringSelection(PRBool aVisibility);
|
||||||
NS_IMETHOD DrawAtPosition(nsIDOMNode* aNode, PRInt32 aOffset);
|
NS_IMETHOD DrawAtPosition(nsIDOMNode* aNode, PRInt32 aOffset);
|
||||||
|
|
||||||
|
NS_IMETHOD SetOptimizeDrawCaret(PRBool aOptimzeDrawCaret);
|
||||||
|
|
||||||
//nsISelectionListener interface
|
//nsISelectionListener interface
|
||||||
NS_IMETHOD NotifySelectionChanged(nsIDOMDocument *aDoc, nsISelection *aSel, short aReason);
|
NS_IMETHOD NotifySelectionChanged(nsIDOMDocument *aDoc, nsISelection *aSel, short aReason);
|
||||||
|
|
||||||
|
@ -103,9 +105,10 @@ protected:
|
||||||
PRPackedBool mReadOnly; // it the caret in readonly state (draws differently)
|
PRPackedBool mReadOnly; // it the caret in readonly state (draws differently)
|
||||||
PRPackedBool mShowDuringSelection; // show when text is selected
|
PRPackedBool mShowDuringSelection; // show when text is selected
|
||||||
|
|
||||||
PRPackedBool mCachedOffsetValid; //whether the cached frame offset is valid
|
PRPackedBool mOptimizeDrawCaret; // flag for optimizing draw caret
|
||||||
nsPoint mCachedFrameOffset; //cached frame offset
|
PRPackedBool mCachedOffsetValid; // whether the cached frame offset is valid
|
||||||
|
nsPoint mCachedFrameOffset; // cached frame offset
|
||||||
|
|
||||||
nsRect mCaretRect; // the last caret rect
|
nsRect mCaretRect; // the last caret rect
|
||||||
nsIFrame* mLastCaretFrame; // store the frame the caret was last drawn in.
|
nsIFrame* mLastCaretFrame; // store the frame the caret was last drawn in.
|
||||||
nsIView* mLastCaretView; // last view that we used for drawing. Cached so we can tell when we need to make a new RC
|
nsIView* mLastCaretView; // last view that we used for drawing. Cached so we can tell when we need to make a new RC
|
||||||
|
|
Загрузка…
Ссылка в новой задаче