fix for setcapture. passes events to the nsHTMLFrame's areaframe when events are trapped to a given frame's view.

This commit is contained in:
mjudge%netscape.com 2000-04-12 03:04:11 +00:00
parent 9553090997
commit f0c0beb50c
19 changed files with 401 additions and 120 deletions

View File

@ -382,7 +382,7 @@ public:
NS_DECL_ISUPPORTS
nsAutoScrollTimer()
: mSelection(0), mTimer(0), mFrame(0), mPresContext(0), mPoint(0,0), mDelay(30)
: mSelection(0), mTimer(0), mFrame(0), mPresContext(0), mPoint(0,0), mScrollPoint(0,0), mDelay(30)
{
NS_INIT_ISUPPORTS();
}
@ -396,7 +396,7 @@ public:
}
}
nsresult Start(nsIPresContext *aPresContext, nsIFrame *aFrame, nsPoint& aPoint)
nsresult Start(nsIPresContext *aPresContext, nsIFrame *aFrame, nsPoint &aPoint)
{
mFrame = aFrame;
mPresContext = aPresContext;
@ -444,11 +444,24 @@ public:
{
if (mSelection && mPresContext && mFrame)
{
mFrameSelection->HandleDrag(mPresContext, mFrame, mPoint);
//the frame passed in here will be a root frame for the view. there is no need to call the constrain
//method here. the root frame has NO content now unfortunately...
PRInt32 startPos = 0;
PRInt32 contentOffsetEnd = 0;
PRBool beginOfContent;
nsCOMPtr<nsIContent> newContent;
nsresult result = mFrame->GetContentAndOffsetsFromPoint(mPresContext, mPoint,
getter_AddRefs(newContent),
startPos, contentOffsetEnd,beginOfContent);
if (NS_SUCCEEDED(result))
{
result = mFrameSelection->HandleClick(newContent, startPos, contentOffsetEnd , PR_TRUE, PR_FALSE, beginOfContent);
}
//mFrameSelection->HandleDrag(mPresContext, mFrame, mPoint);
mSelection->DoAutoScroll(mPresContext, mFrame, mPoint);
}
}
private:
nsSelection *mFrameSelection;
nsDOMSelection *mSelection;
@ -456,6 +469,7 @@ private:
nsIFrame *mFrame;
nsIPresContext *mPresContext;
nsPoint mPoint;
nsPoint mScrollPoint;
PRUint32 mDelay;
};
@ -1442,8 +1456,8 @@ nsSelection::HandleClick(nsIContent *aNewFocus, PRUint32 aContentOffset,
PRBool aMultipleSelection, PRBool aHint)
{
InvalidateDesiredX();
mHint = HINT(aHint);
mHint = HINT(aHint);
// Don't take focus when dragging off of a table
if (!mSelectingTableCells)
return TakeFocus(aNewFocus, aContentOffset, aContentEndOffset, aContinueSelection, aMultipleSelection);
@ -3293,7 +3307,7 @@ nsDOMSelection::StopAutoScrollTimer()
if (mAutoScrollTimer)
return mAutoScrollTimer->Stop();
return NS_OK;
return NS_OK;
}
nsresult
@ -3369,10 +3383,11 @@ nsDOMSelection::DoAutoScroll(nsIPresContext *aPresContext, nsIFrame *aFrame, nsP
// scrollable view's parent hierarchy.
//
nsIView *view = (nsIView*)cView;
nsIView *view = (nsIView*)frameView;
nscoord x, y;
while (view && view != frameView)
while (view && view != cView)
{
result = view->GetParent(view);
@ -3407,8 +3422,8 @@ nsDOMSelection::DoAutoScroll(nsIPresContext *aPresContext, nsIFrame *aFrame, nsP
nsRect bounds;
result = cView->GetBounds(bounds);
result = view->GetBounds(bounds);
scrollableView->GetScrollPosition(bounds.x,bounds.y);
if (NS_SUCCEEDED(result))
{
//
@ -3484,7 +3499,13 @@ nsDOMSelection::DoAutoScroll(nsIPresContext *aPresContext, nsIFrame *aFrame, nsP
viewManager->Composite();
result = scrollableView->ScrollTo(scrollX + dx, scrollY + dy, NS_VMREFRESH_NO_SYNC);
if (mAutoScrollTimer)
result = mAutoScrollTimer->Start(aPresContext, aFrame, aPoint);
{
nsPoint point(aPoint.x + dx,aPoint.y + dy);
result = mAutoScrollTimer->Start(aPresContext, parentFrame, point);
#ifdef DEBUG_SELECTION
printf("point out of view: x=%u, y=%u\n", (point.x), (point.y));
#endif
}
}
}
}
@ -3548,7 +3569,7 @@ nsDOMSelection::AddRange(nsIDOMRange* aRange)
nsCOMPtr<nsIPresContext> presContext;
GetPresContext(getter_AddRefs(presContext));
selectFrames(presContext, aRange, PR_TRUE);
ScrollIntoView();
//ScrollIntoView(); this should not happen automatically
return mFrameSelection->NotifySelectionListeners();
}

View File

@ -19,6 +19,9 @@
*
* Contributor(s):
*/
#include "nsCOMPtr.h"
#include "nsLayoutAtoms.h"
#include "nsFrameTraversal.h"
#include "nsFrameList.h"
@ -211,7 +214,7 @@ NS_IMETHODIMP
nsLeafIterator::Next()
{
//recursive-oid method to get next frame
nsIFrame *result;
nsIFrame *result = nsnull;
nsIFrame *parent = getCurrent();
if (!parent)
parent = getLast();
@ -227,7 +230,8 @@ nsLeafIterator::Next()
result = parent;
}
else {
while(parent){
nsCOMPtr<nsIAtom>atom;
while(parent && NS_SUCCEEDED(parent->GetFrameType(getter_AddRefs(atom))) && atom != nsLayoutAtoms::rootFrame){
if (NS_SUCCEEDED(parent->GetNextSibling(&result)) && result){
parent = result;
while(NS_SUCCEEDED(parent->FirstChild(mPresContext, nsnull,&result)) && result)
@ -238,7 +242,7 @@ nsLeafIterator::Next()
break;
}
else
if (NS_FAILED(parent->GetParent(&result)) || !result){
if (NS_FAILED(parent->GetParent(&result)) || !result || (NS_SUCCEEDED(result->GetFrameType(getter_AddRefs(atom))) && atom == nsLayoutAtoms::rootFrame)){
result = nsnull;
break;
}

View File

@ -3399,7 +3399,7 @@ PresShell::HandleEvent(nsIView *aView,
rv = frame->GetFrameForPoint(mPresContext, eventPoint, NS_FRAME_PAINT_LAYER_BACKGROUND, &mCurrentEventFrame);
if (rv != NS_OK) {
// XXX Is this the right thing to do?
mCurrentEventFrame = nsnull;
mCurrentEventFrame = frame;
aHandled = PR_FALSE;
rv = NS_OK;
}
@ -3421,8 +3421,9 @@ PresShell::HandleEvent(nsIView *aView,
if (rv != NS_OK) {
rv = frame->GetFrameForPoint(mPresContext, eventPoint, NS_FRAME_PAINT_LAYER_BACKGROUND, &mCurrentEventFrame);
if (rv != NS_OK) {
// XXX Is this the right thing to do?
mCurrentEventFrame = nsnull;
// XXX Is this the right thing to do? NO IT ISNT!
mCurrentEventFrame = frame;
//mCurrentEventFrame = nsnull;
aHandled = PR_FALSE;
rv = NS_OK;
}

View File

@ -19,6 +19,9 @@
*
* Contributor(s):
*/
#include "nsCOMPtr.h"
#include "nsLayoutAtoms.h"
#include "nsFrameTraversal.h"
#include "nsFrameList.h"
@ -211,7 +214,7 @@ NS_IMETHODIMP
nsLeafIterator::Next()
{
//recursive-oid method to get next frame
nsIFrame *result;
nsIFrame *result = nsnull;
nsIFrame *parent = getCurrent();
if (!parent)
parent = getLast();
@ -227,7 +230,8 @@ nsLeafIterator::Next()
result = parent;
}
else {
while(parent){
nsCOMPtr<nsIAtom>atom;
while(parent && NS_SUCCEEDED(parent->GetFrameType(getter_AddRefs(atom))) && atom != nsLayoutAtoms::rootFrame){
if (NS_SUCCEEDED(parent->GetNextSibling(&result)) && result){
parent = result;
while(NS_SUCCEEDED(parent->FirstChild(mPresContext, nsnull,&result)) && result)
@ -238,7 +242,7 @@ nsLeafIterator::Next()
break;
}
else
if (NS_FAILED(parent->GetParent(&result)) || !result){
if (NS_FAILED(parent->GetParent(&result)) || !result || (NS_SUCCEEDED(result->GetFrameType(getter_AddRefs(atom))) && atom == nsLayoutAtoms::rootFrame)){
result = nsnull;
break;
}

View File

@ -382,7 +382,7 @@ public:
NS_DECL_ISUPPORTS
nsAutoScrollTimer()
: mSelection(0), mTimer(0), mFrame(0), mPresContext(0), mPoint(0,0), mDelay(30)
: mSelection(0), mTimer(0), mFrame(0), mPresContext(0), mPoint(0,0), mScrollPoint(0,0), mDelay(30)
{
NS_INIT_ISUPPORTS();
}
@ -396,7 +396,7 @@ public:
}
}
nsresult Start(nsIPresContext *aPresContext, nsIFrame *aFrame, nsPoint& aPoint)
nsresult Start(nsIPresContext *aPresContext, nsIFrame *aFrame, nsPoint &aPoint)
{
mFrame = aFrame;
mPresContext = aPresContext;
@ -444,11 +444,24 @@ public:
{
if (mSelection && mPresContext && mFrame)
{
mFrameSelection->HandleDrag(mPresContext, mFrame, mPoint);
//the frame passed in here will be a root frame for the view. there is no need to call the constrain
//method here. the root frame has NO content now unfortunately...
PRInt32 startPos = 0;
PRInt32 contentOffsetEnd = 0;
PRBool beginOfContent;
nsCOMPtr<nsIContent> newContent;
nsresult result = mFrame->GetContentAndOffsetsFromPoint(mPresContext, mPoint,
getter_AddRefs(newContent),
startPos, contentOffsetEnd,beginOfContent);
if (NS_SUCCEEDED(result))
{
result = mFrameSelection->HandleClick(newContent, startPos, contentOffsetEnd , PR_TRUE, PR_FALSE, beginOfContent);
}
//mFrameSelection->HandleDrag(mPresContext, mFrame, mPoint);
mSelection->DoAutoScroll(mPresContext, mFrame, mPoint);
}
}
private:
nsSelection *mFrameSelection;
nsDOMSelection *mSelection;
@ -456,6 +469,7 @@ private:
nsIFrame *mFrame;
nsIPresContext *mPresContext;
nsPoint mPoint;
nsPoint mScrollPoint;
PRUint32 mDelay;
};
@ -1442,8 +1456,8 @@ nsSelection::HandleClick(nsIContent *aNewFocus, PRUint32 aContentOffset,
PRBool aMultipleSelection, PRBool aHint)
{
InvalidateDesiredX();
mHint = HINT(aHint);
mHint = HINT(aHint);
// Don't take focus when dragging off of a table
if (!mSelectingTableCells)
return TakeFocus(aNewFocus, aContentOffset, aContentEndOffset, aContinueSelection, aMultipleSelection);
@ -3293,7 +3307,7 @@ nsDOMSelection::StopAutoScrollTimer()
if (mAutoScrollTimer)
return mAutoScrollTimer->Stop();
return NS_OK;
return NS_OK;
}
nsresult
@ -3369,10 +3383,11 @@ nsDOMSelection::DoAutoScroll(nsIPresContext *aPresContext, nsIFrame *aFrame, nsP
// scrollable view's parent hierarchy.
//
nsIView *view = (nsIView*)cView;
nsIView *view = (nsIView*)frameView;
nscoord x, y;
while (view && view != frameView)
while (view && view != cView)
{
result = view->GetParent(view);
@ -3407,8 +3422,8 @@ nsDOMSelection::DoAutoScroll(nsIPresContext *aPresContext, nsIFrame *aFrame, nsP
nsRect bounds;
result = cView->GetBounds(bounds);
result = view->GetBounds(bounds);
scrollableView->GetScrollPosition(bounds.x,bounds.y);
if (NS_SUCCEEDED(result))
{
//
@ -3484,7 +3499,13 @@ nsDOMSelection::DoAutoScroll(nsIPresContext *aPresContext, nsIFrame *aFrame, nsP
viewManager->Composite();
result = scrollableView->ScrollTo(scrollX + dx, scrollY + dy, NS_VMREFRESH_NO_SYNC);
if (mAutoScrollTimer)
result = mAutoScrollTimer->Start(aPresContext, aFrame, aPoint);
{
nsPoint point(aPoint.x + dx,aPoint.y + dy);
result = mAutoScrollTimer->Start(aPresContext, parentFrame, point);
#ifdef DEBUG_SELECTION
printf("point out of view: x=%u, y=%u\n", (point.x), (point.y));
#endif
}
}
}
}
@ -3548,7 +3569,7 @@ nsDOMSelection::AddRange(nsIDOMRange* aRange)
nsCOMPtr<nsIPresContext> presContext;
GetPresContext(getter_AddRefs(presContext));
selectFrames(presContext, aRange, PR_TRUE);
ScrollIntoView();
//ScrollIntoView(); this should not happen automatically
return mFrameSelection->NotifySelectionListeners();
}

View File

@ -6170,7 +6170,7 @@ nsBlockFrame::HandleEvent(nsIPresContext* aPresContext,
else
return NS_OK; //just stop it
}
return NS_OK;
return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}

View File

@ -6170,7 +6170,7 @@ nsBlockFrame::HandleEvent(nsIPresContext* aPresContext,
else
return NS_OK; //just stop it
}
return NS_OK;
return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}

View File

@ -6170,7 +6170,7 @@ nsBlockFrame::HandleEvent(nsIPresContext* aPresContext,
else
return NS_OK; //just stop it
}
return NS_OK;
return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}

View File

@ -72,6 +72,8 @@
#include "nsILineIterator.h"
// [HACK] Foward Declarations
void ForceDrawFrame(nsIPresContext* aPresContext, nsFrame * aFrame);
PRBool IsSelectable(nsIFrame *aFrame); //checks style to see if we can selected
//non Hack prototypes
#if 0
static void RefreshContentFrames(nsIPresContext* aPresContext, nsIContent * aStartContent, nsIContent * aEndContent);
@ -782,7 +784,11 @@ nsFrame::HandleEvent(nsIPresContext* aPresContext,
{
nsCOMPtr<nsIFrameSelection> frameselection;
if (NS_SUCCEEDED(shell->GetFrameSelection(getter_AddRefs(frameselection))) && frameselection)
frameselection->SetMouseDownState(PR_TRUE);//not important if it fails here
{
frameselection->SetMouseDownState( PR_TRUE);//not important if it fails here
if (!IsMouseCaptured(aPresContext))
CaptureMouse(aPresContext, PR_TRUE);
}
HandlePress(aPresContext, aEvent, aEventStatus);
}break;
case NS_MOUSE_LEFT_BUTTON_UP:
@ -885,6 +891,31 @@ nsFrame::GetDataForTableSelection(nsMouseEvent *aMouseEvent, nsIContent **aParen
return NS_OK;
}
static
PRBool IsSelectable(nsIFrame *aFrame) //checks style to see if we can selected
{
if (!aFrame)
return PR_FALSE;
nsIFrame *parent;
if (NS_FAILED(aFrame->GetParent(&parent)))
return PR_FALSE;
const nsStyleUserInterface* userinterface;
aFrame->GetStyleData(eStyleStruct_UserInterface, (const nsStyleStruct*&)userinterface);
if (userinterface) {
if (userinterface->mUserSelect == NS_STYLE_USER_SELECT_AUTO) {
// if 'user-select' isn't set for this frame, use the parent's
if (parent) {
parent->GetStyleData(eStyleStruct_UserInterface, (const nsStyleStruct*&)userinterface);
}
}
if (userinterface->mUserSelect == NS_STYLE_USER_SELECT_NONE) {
return PR_FALSE;//do not continue no selection for this frame.
}
}
return PR_TRUE;//default to true.
}
/**
* Handles the Mouse Press Event for the frame
*/
@ -896,6 +927,18 @@ nsFrame::HandlePress(nsIPresContext* aPresContext,
if (!DisplaySelection(aPresContext)) {
return NS_OK;
}
//IF THIS FRAME IS GENERATED
result = kid->GetFrameState(&frameState);
if (NS_FAILED(result))
return result;
if (frameState & NS_FRAME_GENERATED_CONTENT) {
// It's generated content, so skip it!
skipThisKid = PR_TRUE;
nsMouseEvent *me = (nsMouseEvent *)aEvent;
if (me->clickCount >1 )
return HandleMultiplePress(aPresContext,aEvent,aEventStatus);
@ -903,20 +946,8 @@ nsFrame::HandlePress(nsIPresContext* aPresContext,
// check whether style allows selection
// if not dont tell selection the mouse event even occured.
const nsStyleUserInterface* userinterface;
GetStyleData(eStyleStruct_UserInterface, (const nsStyleStruct*&)userinterface);
if (userinterface) {
if (userinterface->mUserSelect == NS_STYLE_USER_SELECT_AUTO) {
// if 'user-select' isn't set for this frame, use the parent's
if (mParent) {
mParent->GetStyleData(eStyleStruct_UserInterface, (const nsStyleStruct*&)userinterface);
}
}
if (userinterface->mUserSelect == NS_STYLE_USER_SELECT_NONE) {
return NS_OK;//do not continue no selection for this frame.
}
}
if (!IsSelectable(this))
return NS_OK;
nsCOMPtr<nsIPresShell> shell;
nsresult rv = aPresContext->GetShell(getter_AddRefs(shell));
if (NS_SUCCEEDED(rv) && shell) {
@ -933,6 +964,8 @@ nsFrame::HandlePress(nsIPresContext* aPresContext,
if (NS_SUCCEEDED(shell->GetFrameSelection(getter_AddRefs(frameselection))) && frameselection)
{
frameselection->SetMouseDownState(PR_TRUE);//not important if it fails here
if (!IsMouseCaptured(aPresContext))
CaptureMouse(aPresContext, PR_TRUE);
nsCOMPtr<nsIContent>parentContent;
PRInt32 contentOffset;
@ -1096,6 +1129,8 @@ NS_IMETHODIMP nsFrame::HandleRelease(nsIPresContext* aPresContext,
nsCOMPtr<nsIFrameSelection> frameselection;
result = presShell->GetFrameSelection(getter_AddRefs(frameselection));
if (IsMouseCaptured(aPresContext))
CaptureMouse(aPresContext, PR_FALSE);
if (NS_SUCCEEDED(result) && frameselection)
frameselection->StopAutoScrollTimer();
@ -1996,19 +2031,8 @@ nsFrame::SetSelected(nsIPresContext* aPresContext, nsIDOMRange *aRange,PRBool aS
if (aSelected && ParentDisablesSelection())
return NS_OK;
// check whether style allows selection
const nsStyleUserInterface* userinterface;
GetStyleData(eStyleStruct_UserInterface, (const nsStyleStruct*&)userinterface);
if (userinterface) {
if (userinterface->mUserSelect == NS_STYLE_USER_SELECT_AUTO) {
// if 'user-select' isn't set for this frame, use the parent's
if (mParent) {
mParent->GetStyleData(eStyleStruct_UserInterface, (const nsStyleStruct*&)userinterface);
}
}
if (userinterface->mUserSelect == NS_STYLE_USER_SELECT_NONE) {
return NS_OK;//do not continue no selection for this frame.
}
}
if (!IsSelectable(this))
return NS_OK;
/* nsresult rv;
@ -2230,11 +2254,16 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIPresContext* aPresContext,
nsPoint point;
point.x = aPos->mDesiredX;
point.y = 0;
result = resultFrame->GetContentAndOffsetsFromPoint(context,point,
result = NS_ERROR_FAILURE;
nsIView* view;//if frame has a view. then stop. no doubleclicking into views
if (NS_FAILED(resultFrame->GetView(aPresContext, &view)) || !view)
{
result = resultFrame->GetContentAndOffsetsFromPoint(context,point,
getter_AddRefs(aPos->mResultContent),
aPos->mContentOffset,
aPos->mContentOffsetEnd,
aPos->mPreferLeft);
}
if (NS_SUCCEEDED(result))
{
found = PR_TRUE;
@ -2272,6 +2301,8 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIPresContext* aPresContext,
result = resultFrame->GetContentAndOffsetsFromPoint(context,point,
getter_AddRefs(aPos->mResultContent), aPos->mContentOffset,
aPos->mContentOffsetEnd, aPos->mPreferLeft);
if (!IsSelectable(resultFrame))
return NS_ERROR_FAILURE;//cant go to unselectable frame
if (NS_SUCCEEDED(result))
{
found = PR_TRUE;
@ -2344,7 +2375,7 @@ nsFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
(aPos->mDirection == eDirPrevious && newOffset >= aPos->mStartOffset))
{
result = GetFrameFromDirection(aPresContext, aPos);
if (NS_FAILED(result) || !aPos->mResultFrame)
if (NS_FAILED(result) || !aPos->mResultFrame || !IsSelectable(aPos->mResultFrame))
{
return result?result:NS_ERROR_FAILURE;
}
@ -2511,7 +2542,7 @@ nsFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
nsIView * view; //used for call of get offset from view
nextFrame->GetOffsetFromView(aPresContext, offsetPoint, &view);
offsetPoint.x = 2* usedRect.width; //2* just to be sure we are off the edge
offsetPoint.x += 2* usedRect.width; //2* just to be sure we are off the edge
result = nextFrame->GetContentAndOffsetsFromPoint(context,
offsetPoint,
@ -2661,6 +2692,8 @@ nsFrame::GetFrameFromDirection(nsIPresContext* aPresContext, nsPeekOffsetStruct
//we must CAST here to an nsIFrame. nsIFrame doesnt really follow the rules
//for speed reasons
nsIFrame *newFrame = (nsIFrame *)isupports;
if (!IsSelectable(newFrame))
return NS_ERROR_FAILURE;
if (aPos->mDirection == eDirNext)
aPos->mStartOffset = 0;
else
@ -2827,6 +2860,63 @@ nsresult nsFrame::CreateAndPostReflowCommand(nsIPresShell* aPresS
return rv;
}
nsresult
nsFrame::CaptureMouse(nsIPresContext* aPresContext, PRBool aGrabMouseEvents)
{
// get its view
nsIView* view = nsnull;
nsIFrame *parent;//might be THIS frame thats ok
nsresult rv = GetParentWithView(aPresContext, &parent);
if (!parent || NS_FAILED(rv))
return rv?rv:NS_ERROR_FAILURE;
parent->GetView(aPresContext,&view);
nsCOMPtr<nsIViewManager> viewMan;
PRBool result;
if (view) {
view->GetViewManager(*getter_AddRefs(viewMan));
if (viewMan) {
if (aGrabMouseEvents) {
viewMan->GrabMouseEvents(view,result);
} else {
viewMan->GrabMouseEvents(nsnull,result);
}
}
}
return NS_OK;
}
PRBool
nsFrame::IsMouseCaptured(nsIPresContext* aPresContext)
{
// get its view
nsIView* view = nsnull;
nsIFrame *parent;//might be THIS frame thats ok
nsresult rv = GetParentWithView(aPresContext, &parent);
if (!parent || NS_FAILED(rv))
return rv?rv:NS_ERROR_FAILURE;
parent->GetView(aPresContext,&view);
nsCOMPtr<nsIViewManager> viewMan;
if (view) {
view->GetViewManager(*getter_AddRefs(viewMan));
if (viewMan) {
nsIView* grabbingView;
viewMan->GetMouseEventGrabber(grabbingView);
if (grabbingView == view)
return PR_TRUE;
}
}
return PR_FALSE;
}
#ifdef NS_DEBUG
static void
GetTagName(nsFrame* aFrame, nsIContent* aContent, PRIntn aResultSize,
@ -2897,4 +2987,5 @@ nsFrame::VerifyDirtyBitSet(nsIFrame* aFrameList)
}
}
#endif

View File

@ -339,6 +339,10 @@ public:
nsIAtom* aAttribute,
nsIAtom* aListName);
//Mouse Capturing code used by the frames to tell the view to capture all the following events
nsresult CaptureMouse(nsIPresContext* aPresContext, PRBool aGrabMouseEvents);
PRBool IsMouseCaptured(nsIPresContext* aPresContext);
#ifdef NS_DEBUG
/**
* Tracing method that writes a method enter/exit routine to the

View File

@ -417,8 +417,17 @@ RootFrame::HandleEvent(nsIPresContext* aPresContext,
if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP ||
aEvent->message == NS_MOUSE_MIDDLE_BUTTON_UP ||
aEvent->message == NS_MOUSE_RIGHT_BUTTON_UP) {
nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
aEvent->message == NS_MOUSE_RIGHT_BUTTON_UP ||
aEvent->message == NS_MOUSE_MOVE ) {
nsIFrame *firstChild;
nsresult rv = FirstChild(aPresContext,nsnull,&firstChild);
//root frame needs to pass mouse events to its area frame so that mouse movement
//and selection code will work properly. this will still have the necessary effects
//that would have happened if nsFrame::HandleEvent was called.
if (NS_SUCCEEDED(rv) && firstChild)
firstChild->HandleEvent(aPresContext, aEvent, aEventStatus);
else
nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}
return NS_OK;

View File

@ -382,7 +382,7 @@ public:
NS_DECL_ISUPPORTS
nsAutoScrollTimer()
: mSelection(0), mTimer(0), mFrame(0), mPresContext(0), mPoint(0,0), mDelay(30)
: mSelection(0), mTimer(0), mFrame(0), mPresContext(0), mPoint(0,0), mScrollPoint(0,0), mDelay(30)
{
NS_INIT_ISUPPORTS();
}
@ -396,7 +396,7 @@ public:
}
}
nsresult Start(nsIPresContext *aPresContext, nsIFrame *aFrame, nsPoint& aPoint)
nsresult Start(nsIPresContext *aPresContext, nsIFrame *aFrame, nsPoint &aPoint)
{
mFrame = aFrame;
mPresContext = aPresContext;
@ -444,11 +444,24 @@ public:
{
if (mSelection && mPresContext && mFrame)
{
mFrameSelection->HandleDrag(mPresContext, mFrame, mPoint);
//the frame passed in here will be a root frame for the view. there is no need to call the constrain
//method here. the root frame has NO content now unfortunately...
PRInt32 startPos = 0;
PRInt32 contentOffsetEnd = 0;
PRBool beginOfContent;
nsCOMPtr<nsIContent> newContent;
nsresult result = mFrame->GetContentAndOffsetsFromPoint(mPresContext, mPoint,
getter_AddRefs(newContent),
startPos, contentOffsetEnd,beginOfContent);
if (NS_SUCCEEDED(result))
{
result = mFrameSelection->HandleClick(newContent, startPos, contentOffsetEnd , PR_TRUE, PR_FALSE, beginOfContent);
}
//mFrameSelection->HandleDrag(mPresContext, mFrame, mPoint);
mSelection->DoAutoScroll(mPresContext, mFrame, mPoint);
}
}
private:
nsSelection *mFrameSelection;
nsDOMSelection *mSelection;
@ -456,6 +469,7 @@ private:
nsIFrame *mFrame;
nsIPresContext *mPresContext;
nsPoint mPoint;
nsPoint mScrollPoint;
PRUint32 mDelay;
};
@ -1442,8 +1456,8 @@ nsSelection::HandleClick(nsIContent *aNewFocus, PRUint32 aContentOffset,
PRBool aMultipleSelection, PRBool aHint)
{
InvalidateDesiredX();
mHint = HINT(aHint);
mHint = HINT(aHint);
// Don't take focus when dragging off of a table
if (!mSelectingTableCells)
return TakeFocus(aNewFocus, aContentOffset, aContentEndOffset, aContinueSelection, aMultipleSelection);
@ -3293,7 +3307,7 @@ nsDOMSelection::StopAutoScrollTimer()
if (mAutoScrollTimer)
return mAutoScrollTimer->Stop();
return NS_OK;
return NS_OK;
}
nsresult
@ -3369,10 +3383,11 @@ nsDOMSelection::DoAutoScroll(nsIPresContext *aPresContext, nsIFrame *aFrame, nsP
// scrollable view's parent hierarchy.
//
nsIView *view = (nsIView*)cView;
nsIView *view = (nsIView*)frameView;
nscoord x, y;
while (view && view != frameView)
while (view && view != cView)
{
result = view->GetParent(view);
@ -3407,8 +3422,8 @@ nsDOMSelection::DoAutoScroll(nsIPresContext *aPresContext, nsIFrame *aFrame, nsP
nsRect bounds;
result = cView->GetBounds(bounds);
result = view->GetBounds(bounds);
scrollableView->GetScrollPosition(bounds.x,bounds.y);
if (NS_SUCCEEDED(result))
{
//
@ -3484,7 +3499,13 @@ nsDOMSelection::DoAutoScroll(nsIPresContext *aPresContext, nsIFrame *aFrame, nsP
viewManager->Composite();
result = scrollableView->ScrollTo(scrollX + dx, scrollY + dy, NS_VMREFRESH_NO_SYNC);
if (mAutoScrollTimer)
result = mAutoScrollTimer->Start(aPresContext, aFrame, aPoint);
{
nsPoint point(aPoint.x + dx,aPoint.y + dy);
result = mAutoScrollTimer->Start(aPresContext, parentFrame, point);
#ifdef DEBUG_SELECTION
printf("point out of view: x=%u, y=%u\n", (point.x), (point.y));
#endif
}
}
}
}
@ -3548,7 +3569,7 @@ nsDOMSelection::AddRange(nsIDOMRange* aRange)
nsCOMPtr<nsIPresContext> presContext;
GetPresContext(getter_AddRefs(presContext));
selectFrames(presContext, aRange, PR_TRUE);
ScrollIntoView();
//ScrollIntoView(); this should not happen automatically
return mFrameSelection->NotifySelectionListeners();
}

View File

@ -6170,7 +6170,7 @@ nsBlockFrame::HandleEvent(nsIPresContext* aPresContext,
else
return NS_OK; //just stop it
}
return NS_OK;
return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}

View File

@ -6170,7 +6170,7 @@ nsBlockFrame::HandleEvent(nsIPresContext* aPresContext,
else
return NS_OK; //just stop it
}
return NS_OK;
return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}

View File

@ -6170,7 +6170,7 @@ nsBlockFrame::HandleEvent(nsIPresContext* aPresContext,
else
return NS_OK; //just stop it
}
return NS_OK;
return nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}

View File

@ -72,6 +72,8 @@
#include "nsILineIterator.h"
// [HACK] Foward Declarations
void ForceDrawFrame(nsIPresContext* aPresContext, nsFrame * aFrame);
PRBool IsSelectable(nsIFrame *aFrame); //checks style to see if we can selected
//non Hack prototypes
#if 0
static void RefreshContentFrames(nsIPresContext* aPresContext, nsIContent * aStartContent, nsIContent * aEndContent);
@ -782,7 +784,11 @@ nsFrame::HandleEvent(nsIPresContext* aPresContext,
{
nsCOMPtr<nsIFrameSelection> frameselection;
if (NS_SUCCEEDED(shell->GetFrameSelection(getter_AddRefs(frameselection))) && frameselection)
frameselection->SetMouseDownState(PR_TRUE);//not important if it fails here
{
frameselection->SetMouseDownState( PR_TRUE);//not important if it fails here
if (!IsMouseCaptured(aPresContext))
CaptureMouse(aPresContext, PR_TRUE);
}
HandlePress(aPresContext, aEvent, aEventStatus);
}break;
case NS_MOUSE_LEFT_BUTTON_UP:
@ -885,6 +891,31 @@ nsFrame::GetDataForTableSelection(nsMouseEvent *aMouseEvent, nsIContent **aParen
return NS_OK;
}
static
PRBool IsSelectable(nsIFrame *aFrame) //checks style to see if we can selected
{
if (!aFrame)
return PR_FALSE;
nsIFrame *parent;
if (NS_FAILED(aFrame->GetParent(&parent)))
return PR_FALSE;
const nsStyleUserInterface* userinterface;
aFrame->GetStyleData(eStyleStruct_UserInterface, (const nsStyleStruct*&)userinterface);
if (userinterface) {
if (userinterface->mUserSelect == NS_STYLE_USER_SELECT_AUTO) {
// if 'user-select' isn't set for this frame, use the parent's
if (parent) {
parent->GetStyleData(eStyleStruct_UserInterface, (const nsStyleStruct*&)userinterface);
}
}
if (userinterface->mUserSelect == NS_STYLE_USER_SELECT_NONE) {
return PR_FALSE;//do not continue no selection for this frame.
}
}
return PR_TRUE;//default to true.
}
/**
* Handles the Mouse Press Event for the frame
*/
@ -896,6 +927,18 @@ nsFrame::HandlePress(nsIPresContext* aPresContext,
if (!DisplaySelection(aPresContext)) {
return NS_OK;
}
//IF THIS FRAME IS GENERATED
result = kid->GetFrameState(&frameState);
if (NS_FAILED(result))
return result;
if (frameState & NS_FRAME_GENERATED_CONTENT) {
// It's generated content, so skip it!
skipThisKid = PR_TRUE;
nsMouseEvent *me = (nsMouseEvent *)aEvent;
if (me->clickCount >1 )
return HandleMultiplePress(aPresContext,aEvent,aEventStatus);
@ -903,20 +946,8 @@ nsFrame::HandlePress(nsIPresContext* aPresContext,
// check whether style allows selection
// if not dont tell selection the mouse event even occured.
const nsStyleUserInterface* userinterface;
GetStyleData(eStyleStruct_UserInterface, (const nsStyleStruct*&)userinterface);
if (userinterface) {
if (userinterface->mUserSelect == NS_STYLE_USER_SELECT_AUTO) {
// if 'user-select' isn't set for this frame, use the parent's
if (mParent) {
mParent->GetStyleData(eStyleStruct_UserInterface, (const nsStyleStruct*&)userinterface);
}
}
if (userinterface->mUserSelect == NS_STYLE_USER_SELECT_NONE) {
return NS_OK;//do not continue no selection for this frame.
}
}
if (!IsSelectable(this))
return NS_OK;
nsCOMPtr<nsIPresShell> shell;
nsresult rv = aPresContext->GetShell(getter_AddRefs(shell));
if (NS_SUCCEEDED(rv) && shell) {
@ -933,6 +964,8 @@ nsFrame::HandlePress(nsIPresContext* aPresContext,
if (NS_SUCCEEDED(shell->GetFrameSelection(getter_AddRefs(frameselection))) && frameselection)
{
frameselection->SetMouseDownState(PR_TRUE);//not important if it fails here
if (!IsMouseCaptured(aPresContext))
CaptureMouse(aPresContext, PR_TRUE);
nsCOMPtr<nsIContent>parentContent;
PRInt32 contentOffset;
@ -1096,6 +1129,8 @@ NS_IMETHODIMP nsFrame::HandleRelease(nsIPresContext* aPresContext,
nsCOMPtr<nsIFrameSelection> frameselection;
result = presShell->GetFrameSelection(getter_AddRefs(frameselection));
if (IsMouseCaptured(aPresContext))
CaptureMouse(aPresContext, PR_FALSE);
if (NS_SUCCEEDED(result) && frameselection)
frameselection->StopAutoScrollTimer();
@ -1996,19 +2031,8 @@ nsFrame::SetSelected(nsIPresContext* aPresContext, nsIDOMRange *aRange,PRBool aS
if (aSelected && ParentDisablesSelection())
return NS_OK;
// check whether style allows selection
const nsStyleUserInterface* userinterface;
GetStyleData(eStyleStruct_UserInterface, (const nsStyleStruct*&)userinterface);
if (userinterface) {
if (userinterface->mUserSelect == NS_STYLE_USER_SELECT_AUTO) {
// if 'user-select' isn't set for this frame, use the parent's
if (mParent) {
mParent->GetStyleData(eStyleStruct_UserInterface, (const nsStyleStruct*&)userinterface);
}
}
if (userinterface->mUserSelect == NS_STYLE_USER_SELECT_NONE) {
return NS_OK;//do not continue no selection for this frame.
}
}
if (!IsSelectable(this))
return NS_OK;
/* nsresult rv;
@ -2230,11 +2254,16 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIPresContext* aPresContext,
nsPoint point;
point.x = aPos->mDesiredX;
point.y = 0;
result = resultFrame->GetContentAndOffsetsFromPoint(context,point,
result = NS_ERROR_FAILURE;
nsIView* view;//if frame has a view. then stop. no doubleclicking into views
if (NS_FAILED(resultFrame->GetView(aPresContext, &view)) || !view)
{
result = resultFrame->GetContentAndOffsetsFromPoint(context,point,
getter_AddRefs(aPos->mResultContent),
aPos->mContentOffset,
aPos->mContentOffsetEnd,
aPos->mPreferLeft);
}
if (NS_SUCCEEDED(result))
{
found = PR_TRUE;
@ -2272,6 +2301,8 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsIPresContext* aPresContext,
result = resultFrame->GetContentAndOffsetsFromPoint(context,point,
getter_AddRefs(aPos->mResultContent), aPos->mContentOffset,
aPos->mContentOffsetEnd, aPos->mPreferLeft);
if (!IsSelectable(resultFrame))
return NS_ERROR_FAILURE;//cant go to unselectable frame
if (NS_SUCCEEDED(result))
{
found = PR_TRUE;
@ -2344,7 +2375,7 @@ nsFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
(aPos->mDirection == eDirPrevious && newOffset >= aPos->mStartOffset))
{
result = GetFrameFromDirection(aPresContext, aPos);
if (NS_FAILED(result) || !aPos->mResultFrame)
if (NS_FAILED(result) || !aPos->mResultFrame || !IsSelectable(aPos->mResultFrame))
{
return result?result:NS_ERROR_FAILURE;
}
@ -2511,7 +2542,7 @@ nsFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos)
nsIView * view; //used for call of get offset from view
nextFrame->GetOffsetFromView(aPresContext, offsetPoint, &view);
offsetPoint.x = 2* usedRect.width; //2* just to be sure we are off the edge
offsetPoint.x += 2* usedRect.width; //2* just to be sure we are off the edge
result = nextFrame->GetContentAndOffsetsFromPoint(context,
offsetPoint,
@ -2661,6 +2692,8 @@ nsFrame::GetFrameFromDirection(nsIPresContext* aPresContext, nsPeekOffsetStruct
//we must CAST here to an nsIFrame. nsIFrame doesnt really follow the rules
//for speed reasons
nsIFrame *newFrame = (nsIFrame *)isupports;
if (!IsSelectable(newFrame))
return NS_ERROR_FAILURE;
if (aPos->mDirection == eDirNext)
aPos->mStartOffset = 0;
else
@ -2827,6 +2860,63 @@ nsresult nsFrame::CreateAndPostReflowCommand(nsIPresShell* aPresS
return rv;
}
nsresult
nsFrame::CaptureMouse(nsIPresContext* aPresContext, PRBool aGrabMouseEvents)
{
// get its view
nsIView* view = nsnull;
nsIFrame *parent;//might be THIS frame thats ok
nsresult rv = GetParentWithView(aPresContext, &parent);
if (!parent || NS_FAILED(rv))
return rv?rv:NS_ERROR_FAILURE;
parent->GetView(aPresContext,&view);
nsCOMPtr<nsIViewManager> viewMan;
PRBool result;
if (view) {
view->GetViewManager(*getter_AddRefs(viewMan));
if (viewMan) {
if (aGrabMouseEvents) {
viewMan->GrabMouseEvents(view,result);
} else {
viewMan->GrabMouseEvents(nsnull,result);
}
}
}
return NS_OK;
}
PRBool
nsFrame::IsMouseCaptured(nsIPresContext* aPresContext)
{
// get its view
nsIView* view = nsnull;
nsIFrame *parent;//might be THIS frame thats ok
nsresult rv = GetParentWithView(aPresContext, &parent);
if (!parent || NS_FAILED(rv))
return rv?rv:NS_ERROR_FAILURE;
parent->GetView(aPresContext,&view);
nsCOMPtr<nsIViewManager> viewMan;
if (view) {
view->GetViewManager(*getter_AddRefs(viewMan));
if (viewMan) {
nsIView* grabbingView;
viewMan->GetMouseEventGrabber(grabbingView);
if (grabbingView == view)
return PR_TRUE;
}
}
return PR_FALSE;
}
#ifdef NS_DEBUG
static void
GetTagName(nsFrame* aFrame, nsIContent* aContent, PRIntn aResultSize,
@ -2897,4 +2987,5 @@ nsFrame::VerifyDirtyBitSet(nsIFrame* aFrameList)
}
}
#endif

View File

@ -339,6 +339,10 @@ public:
nsIAtom* aAttribute,
nsIAtom* aListName);
//Mouse Capturing code used by the frames to tell the view to capture all the following events
nsresult CaptureMouse(nsIPresContext* aPresContext, PRBool aGrabMouseEvents);
PRBool IsMouseCaptured(nsIPresContext* aPresContext);
#ifdef NS_DEBUG
/**
* Tracing method that writes a method enter/exit routine to the

View File

@ -417,8 +417,17 @@ RootFrame::HandleEvent(nsIPresContext* aPresContext,
if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP ||
aEvent->message == NS_MOUSE_MIDDLE_BUTTON_UP ||
aEvent->message == NS_MOUSE_RIGHT_BUTTON_UP) {
nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
aEvent->message == NS_MOUSE_RIGHT_BUTTON_UP ||
aEvent->message == NS_MOUSE_MOVE ) {
nsIFrame *firstChild;
nsresult rv = FirstChild(aPresContext,nsnull,&firstChild);
//root frame needs to pass mouse events to its area frame so that mouse movement
//and selection code will work properly. this will still have the necessary effects
//that would have happened if nsFrame::HandleEvent was called.
if (NS_SUCCEEDED(rv) && firstChild)
firstChild->HandleEvent(aPresContext, aEvent, aEventStatus);
else
nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}
return NS_OK;

View File

@ -3399,7 +3399,7 @@ PresShell::HandleEvent(nsIView *aView,
rv = frame->GetFrameForPoint(mPresContext, eventPoint, NS_FRAME_PAINT_LAYER_BACKGROUND, &mCurrentEventFrame);
if (rv != NS_OK) {
// XXX Is this the right thing to do?
mCurrentEventFrame = nsnull;
mCurrentEventFrame = frame;
aHandled = PR_FALSE;
rv = NS_OK;
}
@ -3421,8 +3421,9 @@ PresShell::HandleEvent(nsIView *aView,
if (rv != NS_OK) {
rv = frame->GetFrameForPoint(mPresContext, eventPoint, NS_FRAME_PAINT_LAYER_BACKGROUND, &mCurrentEventFrame);
if (rv != NS_OK) {
// XXX Is this the right thing to do?
mCurrentEventFrame = nsnull;
// XXX Is this the right thing to do? NO IT ISNT!
mCurrentEventFrame = frame;
//mCurrentEventFrame = nsnull;
aHandled = PR_FALSE;
rv = NS_OK;
}