From 2a573d79c54f544dd29c7be6f4119a29d12a186b Mon Sep 17 00:00:00 2001 From: "pinkerton%netscape.com" Date: Thu, 15 Feb 2001 22:07:06 +0000 Subject: [PATCH] force trees to synchronously update the area invalidated by a mousewheel scroll. r=bryner,a=hyatt, bug#63465 --- content/events/src/nsEventStateManager.cpp | 84 ++++++--- content/events/src/nsEventStateManager.h | 3 + layout/events/src/nsEventStateManager.cpp | 84 ++++++--- layout/events/src/nsEventStateManager.h | 207 --------------------- 4 files changed, 123 insertions(+), 255 deletions(-) diff --git a/content/events/src/nsEventStateManager.cpp b/content/events/src/nsEventStateManager.cpp index 31e62f7ed59..c62a4e0420f 100644 --- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -829,6 +829,64 @@ nsEventStateManager::ChangeTextSize(PRInt32 change) return NS_OK; } + +// +// DoTreeScroll +// +// Trees know best how to deal with scrolling, so use the tree scroll api's instead +// of just blindly scrolling the view. +// +nsresult +nsEventStateManager::DoTreeScroll(nsIPresContext* inPresContext, PRInt32 inNumLines, + PRBool inScrollPage, nsITreeFrame* inTreeFrame) +{ + PRInt32 scrollIndex, visibleRows; + inTreeFrame->GetIndexOfFirstVisibleRow(&scrollIndex); + inTreeFrame->GetNumberOfVisibleRows(&visibleRows); + + if (inScrollPage) + scrollIndex += ((inNumLines > 0) ? visibleRows : -visibleRows); + else + scrollIndex += inNumLines; + + if (scrollIndex < 0) + scrollIndex = 0; + else { + PRInt32 numRows; + inTreeFrame->GetRowCount(&numRows); + PRInt32 lastPageTopRow = numRows - visibleRows; + if (scrollIndex > lastPageTopRow) + scrollIndex = lastPageTopRow; + } + + inTreeFrame->ScrollToIndex(scrollIndex); + + // we have to do a sync update for mac because if we scroll too quickly + // w/out going back to the main event loop we can easily scroll the wrong + // bits and it looks like garbage (bug 63465). + nsIFrame* frame = nsnull; + if ( NS_SUCCEEDED(inTreeFrame->QueryInterface(NS_GET_IID(nsIFrame), &frame)) ) { + nsIView* treeView = nsnull; + frame->GetView(inPresContext, &treeView); + if (!treeView) { + nsIFrame* frameWithView; + frame->GetParentWithView(inPresContext, &frameWithView); + if (frameWithView) + frameWithView->GetView(inPresContext, &treeView); + else + return NS_ERROR_FAILURE; + } + if (treeView) + ForceViewUpdate(treeView); + } + else + return NS_ERROR_FAILURE; + + return NS_OK; + +} // DoTreeScroll + + nsresult nsEventStateManager::DoWheelScroll(nsIPresContext* aPresContext, nsIFrame* aTargetFrame, @@ -850,30 +908,8 @@ nsEventStateManager::DoWheelScroll(nsIPresContext* aPresContext, break; curFrame->GetParent(&curFrame); } - - if (treeFrame) { - PRInt32 scrollIndex, visibleRows; - treeFrame->GetIndexOfFirstVisibleRow(&scrollIndex); - treeFrame->GetNumberOfVisibleRows(&visibleRows); - - if (scrollPage) - scrollIndex += ((numLines > 0) ? visibleRows : -visibleRows); - else - scrollIndex += numLines; - - if (scrollIndex < 0) - scrollIndex = 0; - else { - PRInt32 numRows, lastPageTopRow; - treeFrame->GetRowCount(&numRows); - lastPageTopRow = numRows - visibleRows; - if (scrollIndex > lastPageTopRow) - scrollIndex = lastPageTopRow; - } - - treeFrame->ScrollToIndex(scrollIndex); - return NS_OK; - } + if (treeFrame) + return DoTreeScroll(aPresContext, numLines, scrollPage, treeFrame); nsCOMPtr presShell; aPresContext->GetShell(getter_AddRefs(presShell)); diff --git a/content/events/src/nsEventStateManager.h b/content/events/src/nsEventStateManager.h index 5c7ef7f3cb4..db5546e92e2 100644 --- a/content/events/src/nsEventStateManager.h +++ b/content/events/src/nsEventStateManager.h @@ -34,6 +34,7 @@ class nsIDocument; class nsIScrollableView; class nsIPresShell; +class nsITreeFrame; /* * Event listener manager @@ -128,6 +129,8 @@ protected: nsIFrame* aTargetFrame, nsMouseScrollEvent* msEvent, PRInt32 numLines, PRBool scrollPage, PRBool aUseTargetFrame); + nsresult DoTreeScroll(nsIPresContext* inPresContext, PRInt32 inNumLines, + PRBool inScrollPage, nsITreeFrame* inTreeFrame); void ForceViewUpdate(nsIView* aView); nsresult getPrefService(); nsresult ChangeTextSize(PRInt32 change); diff --git a/layout/events/src/nsEventStateManager.cpp b/layout/events/src/nsEventStateManager.cpp index 31e62f7ed59..c62a4e0420f 100644 --- a/layout/events/src/nsEventStateManager.cpp +++ b/layout/events/src/nsEventStateManager.cpp @@ -829,6 +829,64 @@ nsEventStateManager::ChangeTextSize(PRInt32 change) return NS_OK; } + +// +// DoTreeScroll +// +// Trees know best how to deal with scrolling, so use the tree scroll api's instead +// of just blindly scrolling the view. +// +nsresult +nsEventStateManager::DoTreeScroll(nsIPresContext* inPresContext, PRInt32 inNumLines, + PRBool inScrollPage, nsITreeFrame* inTreeFrame) +{ + PRInt32 scrollIndex, visibleRows; + inTreeFrame->GetIndexOfFirstVisibleRow(&scrollIndex); + inTreeFrame->GetNumberOfVisibleRows(&visibleRows); + + if (inScrollPage) + scrollIndex += ((inNumLines > 0) ? visibleRows : -visibleRows); + else + scrollIndex += inNumLines; + + if (scrollIndex < 0) + scrollIndex = 0; + else { + PRInt32 numRows; + inTreeFrame->GetRowCount(&numRows); + PRInt32 lastPageTopRow = numRows - visibleRows; + if (scrollIndex > lastPageTopRow) + scrollIndex = lastPageTopRow; + } + + inTreeFrame->ScrollToIndex(scrollIndex); + + // we have to do a sync update for mac because if we scroll too quickly + // w/out going back to the main event loop we can easily scroll the wrong + // bits and it looks like garbage (bug 63465). + nsIFrame* frame = nsnull; + if ( NS_SUCCEEDED(inTreeFrame->QueryInterface(NS_GET_IID(nsIFrame), &frame)) ) { + nsIView* treeView = nsnull; + frame->GetView(inPresContext, &treeView); + if (!treeView) { + nsIFrame* frameWithView; + frame->GetParentWithView(inPresContext, &frameWithView); + if (frameWithView) + frameWithView->GetView(inPresContext, &treeView); + else + return NS_ERROR_FAILURE; + } + if (treeView) + ForceViewUpdate(treeView); + } + else + return NS_ERROR_FAILURE; + + return NS_OK; + +} // DoTreeScroll + + nsresult nsEventStateManager::DoWheelScroll(nsIPresContext* aPresContext, nsIFrame* aTargetFrame, @@ -850,30 +908,8 @@ nsEventStateManager::DoWheelScroll(nsIPresContext* aPresContext, break; curFrame->GetParent(&curFrame); } - - if (treeFrame) { - PRInt32 scrollIndex, visibleRows; - treeFrame->GetIndexOfFirstVisibleRow(&scrollIndex); - treeFrame->GetNumberOfVisibleRows(&visibleRows); - - if (scrollPage) - scrollIndex += ((numLines > 0) ? visibleRows : -visibleRows); - else - scrollIndex += numLines; - - if (scrollIndex < 0) - scrollIndex = 0; - else { - PRInt32 numRows, lastPageTopRow; - treeFrame->GetRowCount(&numRows); - lastPageTopRow = numRows - visibleRows; - if (scrollIndex > lastPageTopRow) - scrollIndex = lastPageTopRow; - } - - treeFrame->ScrollToIndex(scrollIndex); - return NS_OK; - } + if (treeFrame) + return DoTreeScroll(aPresContext, numLines, scrollPage, treeFrame); nsCOMPtr presShell; aPresContext->GetShell(getter_AddRefs(presShell)); diff --git a/layout/events/src/nsEventStateManager.h b/layout/events/src/nsEventStateManager.h index 5c7ef7f3cb4..e69de29bb2d 100644 --- a/layout/events/src/nsEventStateManager.h +++ b/layout/events/src/nsEventStateManager.h @@ -1,207 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - */ - -#ifndef nsEventStateManager_h__ -#define nsEventStateManager_h__ - -#include "nsIEventStateManager.h" -#include "nsGUIEvent.h" -#include "nsIContent.h" -#include "nsIPref.h" -#include "nsIObserver.h" -#include "nsWeakReference.h" -#include "nsHashtable.h" - -class nsIDocument; -class nsIScrollableView; -class nsIPresShell; - -/* - * Event listener manager - */ - -class nsEventStateManager : public nsSupportsWeakReference, - public nsIEventStateManager, - public nsIObserver -{ - -public: - nsEventStateManager(); - virtual ~nsEventStateManager(); - - NS_DECL_ISUPPORTS - NS_DECL_NSIOBSERVER - - NS_IMETHOD Init(); - nsresult Shutdown(); - - /* The PreHandleEvent method is called before event dispatch to either - * the DOM or frames. Any processing which must not be prevented or - * cancelled should occur here. Any processing which is intended to - * be conditional based on either DOM or frame processing should occur in - * PostHandleEvent. Any centralized event processing which must occur before - * DOM or frame event handling should occur here as well. - */ - NS_IMETHOD PreHandleEvent(nsIPresContext* aPresContext, - nsEvent *aEvent, - nsIFrame* aTargetFrame, - nsEventStatus* aStatus, - nsIView* aView); - - /* The PostHandleEvent method should contain all system processing which - * should occur conditionally based on DOM or frame processing. It should - * also contain any centralized event processing which must occur after - * DOM and frame processing. - */ - NS_IMETHOD PostHandleEvent(nsIPresContext* aPresContext, - nsEvent *aEvent, - nsIFrame* aTargetFrame, - nsEventStatus* aStatus, - nsIView* aView); - - NS_IMETHOD SetPresContext(nsIPresContext* aPresContext); - NS_IMETHOD ClearFrameRefs(nsIFrame* aFrame); - - NS_IMETHOD GetEventTarget(nsIFrame **aFrame); - NS_IMETHOD GetEventTargetContent(nsEvent* aEvent, nsIContent** aContent); - NS_IMETHOD GetEventRelatedContent(nsIContent** aContent); - - NS_IMETHOD GetContentState(nsIContent *aContent, PRInt32& aState); - NS_IMETHOD SetContentState(nsIContent *aContent, PRInt32 aState); - NS_IMETHOD GetFocusedContent(nsIContent **aContent); - NS_IMETHOD SetFocusedContent(nsIContent* aContent); - - // This is an experiement and may be temporary - NS_IMETHOD ConsumeFocusEvents(PRBool aDoConsume) { mConsumeFocusEvents = aDoConsume; return NS_OK; } - - // Access Key Registration - NS_IMETHOD RegisterAccessKey(nsIFrame * aFrame, nsIContent* aContent, PRUint32 aKey); - NS_IMETHOD UnregisterAccessKey(nsIFrame * aFrame, nsIContent* aContent, PRUint32 aKey); - - NS_IMETHOD SetCursor(PRInt32 aCursor, nsIWidget* aWidget, PRBool aLockCursor); - - //Method for centralized distribution of new DOM events - NS_IMETHOD DispatchNewEvent(nsISupports* aTarget, nsIDOMEvent* aEvent); - -protected: - void UpdateCursor(nsIPresContext* aPresContext, nsEvent* aEvent, nsIFrame* aTargetFrame, nsEventStatus* aStatus); - void GenerateMouseEnterExit(nsIPresContext* aPresContext, nsGUIEvent* aEvent); - void GenerateDragDropEnterExit(nsIPresContext* aPresContext, nsGUIEvent* aEvent); - NS_IMETHOD SetClickCount(nsIPresContext* aPresContext, nsMouseEvent *aEvent, nsEventStatus* aStatus); - NS_IMETHOD CheckForAndDispatchClick(nsIPresContext* aPresContext, nsMouseEvent *aEvent, nsEventStatus* aStatus); - PRBool ChangeFocus(nsIContent* aFocus, nsIFrame* aFocusFrame, PRBool aSetFocus); - void ShiftFocus(PRBool foward); - NS_IMETHOD GetNextTabbableContent(nsIContent* aRootContent, nsIFrame* aFrame, PRBool foward, nsIContent** aResult); - PRInt32 GetNextTabIndex(nsIContent* aParent, PRBool foward); - NS_IMETHOD SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aContent); - PRBool CheckDisabled(nsIContent* aContent); - void EnsureDocument(nsIPresShell* aPresShell); - void EnsureDocument(nsIPresContext* aPresContext); - void FlushPendingEvents(nsIPresContext* aPresContext); - - // These functions are for mousewheel scrolling - nsIScrollableView* GetNearestScrollingView(nsIView* aView); - nsresult GetParentScrollingView(nsMouseScrollEvent* aEvent, - nsIPresContext* aPresContext, - nsIFrame* &targetOuterFrame, - nsIPresContext* &presCtxOuter); - nsresult DoWheelScroll(nsIPresContext* aPresContext, - nsIFrame* aTargetFrame, - nsMouseScrollEvent* msEvent, PRInt32 numLines, - PRBool scrollPage, PRBool aUseTargetFrame); - void ForceViewUpdate(nsIView* aView); - nsresult getPrefService(); - nsresult ChangeTextSize(PRInt32 change); - // end mousewheel functions - - // routines for the d&d gesture tracking state machine - void BeginTrackingDragGesture ( nsGUIEvent* inDownEvent, nsIFrame* inDownFrame ) ; - void StopTrackingDragGesture ( ) ; - void GenerateDragGesture ( nsIPresContext* aPresContext, nsGUIEvent *aEvent ) ; - PRBool IsTrackingDragGesture ( ) const { return mIsTrackingDragGesture; } - - PRBool mSuppressFocusChange; // Used only for Ender text fields to suppress a focus firing on mouse down - - // Return the location of the caret - nsresult GetCaretLocation(nsIContent **caretContent, nsIFrame **caretFrame, PRUint32 *caretOffset); - nsresult MoveFocusToCaret(); - nsresult MoveCaretToFocus(); - nsresult EnsureCaretVisible(nsIPresShell* aPresShell, nsIContent *aContent); - - //Any frames here must be checked for validity in ClearFrameRefs - nsIFrame* mCurrentTarget; - nsIContent* mCurrentTargetContent; - nsIContent* mCurrentRelatedContent; - nsIFrame* mLastMouseOverFrame; - nsCOMPtr mLastMouseOverContent; - nsIFrame* mLastDragOverFrame; - - // member variables for the d&d gesture state machine - PRBool mIsTrackingDragGesture; - nsPoint mGestureDownPoint; - nsIFrame* mGestureDownFrame; - - nsIContent* mLastLeftMouseDownContent; - nsIContent* mLastMiddleMouseDownContent; - nsIContent* mLastRightMouseDownContent; - - nsIContent* mActiveContent; - nsIContent* mHoverContent; - nsIContent* mDragOverContent; - nsIContent* mCurrentFocus; - PRInt32 mCurrentTabIndex; - nsIWidget * mLastWindowToHaveFocus; // last native window to get focus via the evs - PRBool mConsumeFocusEvents; - PRInt32 mLockCursor; - - //Anti-recursive stack controls - nsIContent* mFirstBlurEvent; - nsIContent* mFirstFocusEvent; - nsCOMPtr mFirstMouseOverEventContent; - nsCOMPtr mFirstMouseOutEventContent; - - nsIPresContext* mPresContext; // Not refcnted - nsIDocument* mDocument; // [OWNER], but doesn't need to be. - - PRUint32 mLClickCount; - PRUint32 mMClickCount; - PRUint32 mRClickCount; - - //Hashtable for accesskey support - nsSupportsHashtable *mAccessKeys; - - static PRUint32 mInstanceCount; - - // For mousewheel preferences handling - nsCOMPtr mPrefService; - PRBool m_haveShutdown; - - //Pref for using hierarchical hover (possibly expensive) or not - PRBool hHover; - - // So we don't have to keep checking accessibility.browsewithcaret pref - PRBool mBrowseWithCaret; -}; - -extern nsresult NS_NewEventStateManager(nsIEventStateManager** aInstancePtrResult); - -#endif // nsEventStateManager_h__