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!");
|
||||
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
|
||||
EndUpdateViewBatch();
|
||||
// make sure selection is in view
|
||||
ScrollSelectionIntoView(PR_FALSE);
|
||||
|
||||
// optimizing drawcaret stops
|
||||
if (caret) {
|
||||
caret->SetOptimizeDrawCaret(PR_FALSE);
|
||||
}
|
||||
|
||||
if (mSelState)
|
||||
{
|
||||
// we saved the selection state, but never got to hand it to placeholder
|
||||
|
@ -4340,15 +4359,6 @@ nsresult nsEditor::EndUpdateViewBatch()
|
|||
if (!caret)
|
||||
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)
|
||||
{
|
||||
mUpdateCount--;
|
||||
|
@ -4361,6 +4371,8 @@ nsresult nsEditor::EndUpdateViewBatch()
|
|||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
StCaretHider caretHider(caret);
|
||||
|
||||
// Make sure we enable reflowing before we call
|
||||
// mViewManager->EndUpdateViewBatch(). This will make sure that any
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -334,10 +334,6 @@ nsHTMLEditRules::BeforeEdit(PRInt32 action, nsIEditor::EDirection aDirection)
|
|||
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
|
||||
ConfirmSelectionInBody();
|
||||
// let rules remember the top level action
|
||||
|
@ -365,10 +361,6 @@ nsHTMLEditRules::AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection)
|
|||
// free up selectionState range item
|
||||
(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.
|
||||
* This is difficult, because we cannot know what the level is until after the Bidi algorithm
|
||||
* is applied to the whole paragraph.
|
||||
|
|
|
@ -92,6 +92,7 @@ nsCaret::nsCaret()
|
|||
, mDrawn(PR_FALSE)
|
||||
, mReadOnly(PR_FALSE)
|
||||
, mShowDuringSelection(PR_FALSE)
|
||||
, mOptimizeDrawCaret(PR_FALSE)
|
||||
, mCachedOffsetValid(PR_FALSE)
|
||||
, mLastCaretFrame(nsnull)
|
||||
, mLastCaretView(nsnull)
|
||||
|
@ -445,6 +446,11 @@ NS_IMETHODIMP nsCaret::DrawAtPosition(nsIDOMNode* aNode, PRInt32 aOffset)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsCaret::SetOptimizeDrawCaret(PRBool aOptimzeDrawCaret)
|
||||
{
|
||||
mOptimizeDrawCaret = aOptimzeDrawCaret;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef XP_MAC
|
||||
#pragma mark -
|
||||
|
@ -1069,19 +1075,14 @@ void nsCaret::GetCaretRectAndInvert()
|
|||
{
|
||||
nsRect caretRect = frameRect;
|
||||
|
||||
// if mCachedOffsetValid, apply cached FrameOffset, else compute it again
|
||||
if (!mCachedOffsetValid)
|
||||
{
|
||||
mLastCaretFrame->GetPointFromOffset(presContext, mRendContext, mLastContentOffset, &mCachedFrameOffset);
|
||||
// XXX: The following line was commented out to disable the
|
||||
// offset caching code because it causes bad caret
|
||||
// placement. (bug 194774)
|
||||
//
|
||||
// mCachedOffsetValid = PR_TRUE;
|
||||
// if use cache and cache is ready, apply it, else refresh it
|
||||
if (!mOptimizeDrawCaret || !mCachedOffsetValid) {
|
||||
mLastCaretFrame->GetPointFromOffset(presContext, mRendContext,mLastContentOffset, &mCachedFrameOffset);
|
||||
mCachedOffsetValid = mOptimizeDrawCaret;
|
||||
}
|
||||
|
||||
caretRect += mCachedFrameOffset;
|
||||
|
||||
|
||||
if (mCaretTwipsWidth < 0) // need to re-compute the pixel width
|
||||
{
|
||||
float tDevUnitsToTwips = 15;
|
||||
|
|
|
@ -65,6 +65,8 @@ class nsCaret : public nsICaret,
|
|||
NS_IMETHOD SetVisibilityDuringSelection(PRBool aVisibility);
|
||||
NS_IMETHOD DrawAtPosition(nsIDOMNode* aNode, PRInt32 aOffset);
|
||||
|
||||
NS_IMETHOD SetOptimizeDrawCaret(PRBool aOptimzeDrawCaret);
|
||||
|
||||
//nsISelectionListener interface
|
||||
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 mShowDuringSelection; // show when text is selected
|
||||
|
||||
PRPackedBool mCachedOffsetValid; //whether the cached frame offset is valid
|
||||
nsPoint mCachedFrameOffset; //cached frame offset
|
||||
|
||||
PRPackedBool mOptimizeDrawCaret; // flag for optimizing draw caret
|
||||
PRPackedBool mCachedOffsetValid; // whether the cached frame offset is valid
|
||||
nsPoint mCachedFrameOffset; // cached frame offset
|
||||
|
||||
nsRect mCaretRect; // the last caret rect
|
||||
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
|
||||
|
|
|
@ -125,6 +125,11 @@ public:
|
|||
**/
|
||||
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
|
||||
|
|
|
@ -125,6 +125,11 @@ public:
|
|||
**/
|
||||
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
|
||||
|
|
|
@ -92,6 +92,7 @@ nsCaret::nsCaret()
|
|||
, mDrawn(PR_FALSE)
|
||||
, mReadOnly(PR_FALSE)
|
||||
, mShowDuringSelection(PR_FALSE)
|
||||
, mOptimizeDrawCaret(PR_FALSE)
|
||||
, mCachedOffsetValid(PR_FALSE)
|
||||
, mLastCaretFrame(nsnull)
|
||||
, mLastCaretView(nsnull)
|
||||
|
@ -445,6 +446,11 @@ NS_IMETHODIMP nsCaret::DrawAtPosition(nsIDOMNode* aNode, PRInt32 aOffset)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsCaret::SetOptimizeDrawCaret(PRBool aOptimzeDrawCaret)
|
||||
{
|
||||
mOptimizeDrawCaret = aOptimzeDrawCaret;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef XP_MAC
|
||||
#pragma mark -
|
||||
|
@ -1069,19 +1075,14 @@ void nsCaret::GetCaretRectAndInvert()
|
|||
{
|
||||
nsRect caretRect = frameRect;
|
||||
|
||||
// if mCachedOffsetValid, apply cached FrameOffset, else compute it again
|
||||
if (!mCachedOffsetValid)
|
||||
{
|
||||
mLastCaretFrame->GetPointFromOffset(presContext, mRendContext, mLastContentOffset, &mCachedFrameOffset);
|
||||
// XXX: The following line was commented out to disable the
|
||||
// offset caching code because it causes bad caret
|
||||
// placement. (bug 194774)
|
||||
//
|
||||
// mCachedOffsetValid = PR_TRUE;
|
||||
// if use cache and cache is ready, apply it, else refresh it
|
||||
if (!mOptimizeDrawCaret || !mCachedOffsetValid) {
|
||||
mLastCaretFrame->GetPointFromOffset(presContext, mRendContext,mLastContentOffset, &mCachedFrameOffset);
|
||||
mCachedOffsetValid = mOptimizeDrawCaret;
|
||||
}
|
||||
|
||||
caretRect += mCachedFrameOffset;
|
||||
|
||||
|
||||
if (mCaretTwipsWidth < 0) // need to re-compute the pixel width
|
||||
{
|
||||
float tDevUnitsToTwips = 15;
|
||||
|
|
|
@ -65,6 +65,8 @@ class nsCaret : public nsICaret,
|
|||
NS_IMETHOD SetVisibilityDuringSelection(PRBool aVisibility);
|
||||
NS_IMETHOD DrawAtPosition(nsIDOMNode* aNode, PRInt32 aOffset);
|
||||
|
||||
NS_IMETHOD SetOptimizeDrawCaret(PRBool aOptimzeDrawCaret);
|
||||
|
||||
//nsISelectionListener interface
|
||||
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 mShowDuringSelection; // show when text is selected
|
||||
|
||||
PRPackedBool mCachedOffsetValid; //whether the cached frame offset is valid
|
||||
nsPoint mCachedFrameOffset; //cached frame offset
|
||||
|
||||
PRPackedBool mOptimizeDrawCaret; // flag for optimizing draw caret
|
||||
PRPackedBool mCachedOffsetValid; // whether the cached frame offset is valid
|
||||
nsPoint mCachedFrameOffset; // cached frame offset
|
||||
|
||||
nsRect mCaretRect; // the last caret rect
|
||||
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче