Patch for bug 35296: SetCaretEnabled() takes too long

Patch by Leon.Zhang@sun.com
r=sfraser, sr=kin
This commit is contained in:
henry.jia%sun.com 2003-04-02 05:48:09 +00:00
Родитель e21a8221f4
Коммит b7df6947aa
8 изменённых файлов: 72 добавлений и 43 удалений

Просмотреть файл

@ -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